SQL query giving repetitive results - mysql

I have two tables and I want to fetch select columns from the tables.
table 1 is sfpinventoryinfo and table 2 is opticalportinfo.
Both have NEID as common.
SELECT
sfpinventoryinfo.NEID,
sfpinventoryinfo.SlotNumber,
sfpinventoryinfo.PortNo,
sfpinventoryinfo.PortType,
sfpinventoryinfo.`Type`,
sfpinventoryinfo.SN,
sfpinventoryinfo.GenDes,
sfpinventoryinfo.ApplicationCode,
opticalportinfo.ChannelFrequency
FROM
sfpinventoryinfo
JOIN
opticalportinfo ON sfpinventoryinfo.NEID = opticalportinfo.NEID;
But I am getting weird results:
As shows above result, Slot no 4 should have only 1 entry for port instead of 5

It's likely your opticalportinfo has six rows with the value 13 in NEID. So, your join produces all six rows in your result set.
It's hard to guess the "right" way to choose which of those six rows to use without knowing more about your application. You can hack around the problem with SELECT DISTINCT if you must. But it's a hack.

You clearly have duplicates in one or both tables. In your example data, the entire row looks duplicated, so you could use select distinct so entire rows are not repeated:
SELECT DISTINCT i.NEID, i.SlotNumber, i.PortNo, i.PortType, i.`Type`, i.SN,
i.GenDes, i.ApplicationCode, oi.ChannelFrequency
FROM sfpinventoryinfo i JOIN
opticalportinfo op
ON i.NEID = oi.NEID;
Or perhaps GROUP BY:
SELECT i.NEID, i.SlotNumber, i.PortNo, i.PortType, i.`Type`, i.SN,
i.GenDes, i.ApplicationCode, MAX(oi.ChannelFrequency)
FROM sfpinventoryinfo i JOIN
opticalportinfo op
ON i.NEID = oi.NEID
GROUP BY i.NEID, i.SlotNumber, i.PortNo, i.PortType, i.`Type`, i.SN,
i.GenDes, i.ApplicationCode;
That said, you really need to understand why there are duplicates and adjust your query or fix your data.

Related

SQL Query - Distinct on One Column for Distinct Value of Other (with INNER JOIN)

I appreciate that questions similar to this one have been asked on here before but I have thus far been unable to implement the answers provided into my code both because of wanting to distinguish duplicates in one column only whilst the other stays the same and the INNER JOIN in my code. The INNER JOIN is problematic because most of the provided answers use the PARTITION function and, being a novice with SQL, I do not know how to integrate this with it. Advice just on using INNER JOIN with PARTITION would be useful.
Whilst I could do this post-export in Python (where I will be using the desired output), this code currently outputs ~2 million rows, making it time-consuming to work with and check. Here is the code:
SELECT client_ip_address, language_enum_code
FROM vw_user_session_log AS usl
INNER JOIN vw_user_topic_ownership AS uto
ON usl.user_id = uto.user_id
Using SELECT DISTINCT instead of SELECT gets me closer to the desired output but rather than leaving one duplicate row behind it removes all of them. Advice on using this function whilst preserving one of the duplicate rows would be preferred. I am on a read-only connection to the database so the DELETE FROM approach seen here would only be viable if I could make a temporary query-able table from the query output which I don't think is possible and seems clumsy.
Raw data sample:
user_id: client_ip_address: language_enum_code: (other stuff...)
4 194:4:62:18 107
2 101:9:23:34 14
3 180:4:87:99 15
3 194:4:62:18 15
4 166:1:19:27 107
2 166:1:19:27 14
Desired result:
user_id: client_ip_address: language_enum_code: (other stuff...)
4 194:4:62:18 107
2 101:9:23:34 14
3 180:4:87:99 15
As you can see, any id-enum combination should be filtered to occur only once. The reason this is not any ip-enum combination is that multiple users can connect through the same IP address.
If you don't care which IP address you keep for each user_id / enum combo, then something like this should do:
SELECT user_id, min(client_ip_address), language_enum_code
FROM vw_user_session_log AS usl
INNER JOIN vw_user_topic_ownership AS uto
ON usl.user_id = uto.user_id
where client_ip_address is not null
group by user_id, language_enum_code
Do you simply want aggregation?
SELECT client_ip_address, GROUP_CONCAT(DISTINCT language_enum_code)
FROM vw_user_session_log usl INNER JOIN
vw_user_topic_ownership uto
ON usl.user_id = uto.user_id
GROUP BY client_ip_address;
This will return one row per client_ip_address with each language code in a comma delimited list.
You can also use MIN() or MAX() to get an arbitrary value for language_enum_code for each client_ip_address.

SQL: Trouble returning distinct like values from a subquery and join

query:
select DOG_CD,ANIMAL_CD
from FKAGM
where FKAG = 12024
Displays 3 rows
DOG_CD - ANIMAL_CD are column names and below each column is 3 numerical values yielded from the above query & I have no clue how to draw a table on here to depict that. =(
There is a table called Dog_Animal that has a column called "Name" (Dog_Animal.Name) that I want to join with this above query. I want to join on ANIMAL_CD as FKAGM table and the DOG_ANIMAL table have the ANIMAL_CD column in common. I'd like to display "Name" right next to the ANIMAL_CD column. The issue is when I join the tables it displays like every instance of DOG_CD and ANIMAL_CD within the Dog_Animal table (Which is thousands) something similar to the below illustration. since the Dog_Animal table has thousands of DOG_CD and ANIMAL_CODE fields populated. I just want it to be limited to the three rows that are returned by the above query (Limit or distinct or something) and input the Dog_Animal.Name next to Animal_CD. I've been working on this for an hour and I know it must be so simple, but I can't seem to get it to work. I am not sure if a subquery is needed or exists, or case, or what. If you can figure this out I would be so thankful!
DOG_CD - ANIMAL_CD - Dog_Animal.Name with the same 3 rows of data just now a name included
select
f.DOG_CD,f.ANIMAL_CD,d.name
from FKAGM f
inner join dog_animal d
on d.animal_cd = f.animal_cd
where f.FKAG = 12024;
inner join would work for you. If you only need to limit it to 3 results, add limit 3 order by f.dog_cd at the end of your query.

How to join MySQL 3 tables to filter correct resualt

I wrote mysql for filter resualt there are 3 tables
SELECT
rb_function_booking_events.event_title,
rb_function_booking_events.event_id,
rb_function_category.category_name,
rb_function_category.category_colour,
rb_function_rooms.colour as fc_colour
FROM
rb_function_booking_events
JOIN rb_function_category
ON rb_function_booking_events.category = rb_function_booking_events.category
JOIN rb_function_rooms
ON rb_function_rooms.room_id = rb_function_booking_events.fc_id
WHERE
rb_function_booking_events.booking_date='1396310400'
AND rb_function_booking_events.fc_id='1'
rb_function_booking_events table has 1 row
rb_function_category table has 3 rows
rb_function_rooms table has 6 rows
I want to filter rb_function_booking_events row but when this query execute I got 3 results instead of 1 result, some one please help
As long as you have for one booking_event multiple categories or multiple rooms, you have to decide what to do with them. Look at the result rows and ask yourself what colour you want to see.
You could just concat them with group_concat(distinct category_name), in that case the hint with group by is correct. You could try to see just multiple rows if the results differ, in that case just use select distinct.
But the question "which single room is booked this afternoon" is just invalid if there are many rooms booked.

Adding Points totals from two different tables

I have a point system and I'm trying to add them together. They are on two different tables and I'm using a subquery to get both totals and add them together. Both subqueries on their own work fine, but adding them together gives me a far greater number than it's supposed to.
Here's my query:
SELECT (SUM(tbl_achieve.achieve_points)+SUM(tbl_assign.assign_points))
FROM
(SELECT DISTINCT(tbl_achievements.achieve_id), tbl_achievements.achieve_points FROM tbl_achievements INNER JOIN tbl_studentachieve ON tbl_studentachieve.achieve_id = tbl_achievements.achieve_id AND tbl_studentachieve.student_ID = 8 AND tbl_achievements.achieve_cat = "main" ) as tbl_achieve,
(SELECT DISTINCT(tbl_assignments.assign_id), assign_points FROM tbl_assignments INNER JOIN tbl_studentassign ON tbl_studentassign.assign_id = tbl_studentassign.assign_id WHERE tbl_assignments.assign_cat = "main" AND tbl_studentassign.student_id = 8 AND tbl_studentassign.assign_status = "submitted") as tbl_assign
I think what the problem is, is that it puts both row counts together. So instead of having 2 rows of 10 points, I have 10 rows of 10 points because of the other table's number.
Any idea what I could be missing?
This one is going to be tough without knowing anything about your database. I ran the following query:
select SUM(feed_id) + SUM(user_id) FROM events where 1
on my own db and it returns the correct addition of those complete rows together as only one row. It sounds like that is not what you want, but that is the expected behavior of mySQL. perhaps a more detailed explanation of what you're looking for would help to get you where you need to be. Cheers...

Use of inner join seems to cause entries in a #temp table to disappear

I am brand new to SQL and am working with the following code provided to us by one of our vendors:
SELECT DISTINCT MriPatients.PatientID
INTO #UniquePt
FROM MriPatients
INNER JOIN #TotalPopulation ON MriPatients.PatientID = #TotalPopulation.PatientID
Set #TotalUniquePatients = (Select Count(*) FROM #UniquePt)
What happens is the Set line causes #TotalUniquePatients to be set to 0 even though there are many unique patient ids in our database. That value is then later used as a denominator in a division which causes a divide by 0 error.
Now it seems to me that this is easy to fix by using COUNT DISTINCT on the MriPatients table; then you don't need to create #UniquePt at all...this is the only place that table is used. But, I don't understand why the code as it is gets a 0 result when counting #UniquePt. If you remove the INNER JOIN, the Set returns a correct result...so what does the INNER JOIN do to #UniquePt?
If it matters, we are using SQL Server 2008.
The result is 0 because of 1 of 2 situations:
#TotalPopulation is empty
#TotalPopulation contains no records that have the same value for PatientID as the records in MriPatients
How are you populating #TotalPopulation?
A COUNT DISTINCT won't necessarily do the same thing. It depends on what you fill #TotalPopulation with. If all you want is the number of unique patients in MriPatients then yes, the COUNT DISTINCT will work. But if you're filling #TotalPopulation based on some kind of logic then they're the COUNT DISTINCT won't necessarily give you the same results as the COUNT of the joined tables.
The INNER JOIN causes you to insert ONLY records that have a matching PatientID in the #TotalPopulation table.
I'm guessing you don't, or that table isn't populated, which is causing the issue.
Is there a reason you are joining to it in the first place?