I have a query that I am running in MySQL, and it uses aliases to grab information from the same column twice (to and from destinations from the airport table).
`SELECT AirlineName AS 'Airline Name',
airport1.AirportName AS 'Flying From',
airport2.AirportName AS 'Flying To',
StopType AS 'Number of Stops'
FROM flightjunction
INNER JOIN airline ON flightjunction.FlightAirline = airline.AirlineID
INNER JOIN airport AS airport1 ON flightjunction.FlightFrom = airport1.AirportID
INNER JOIN airport AS airport2 ON flightjunction.FlightTo = airport2.AirportID
INNER JOIN stops ON flightjunction.FlightStops = stops.StopID;`
However, I've noticed that duplicate results are showing up when I run this query. Where am I going wrong? Thank you in advance for your help!
Since you have an inner join on the same table twice in this case, you should add a DISTINCT to eliminate duplicates.
Related
Here is list of my tables and necessary columns
users u .
screen_name,
country,
status
twitter_users_relationship tf. This table have multiple target_screen_name for each screen_name.
screen_name,
target_screen_name,
target_country,
follow_status
user_twitter_action_map ta
screen_name,
action_name,
action_status
user_targeted_countries utc .This table have multiple countries for each screen_name
screen_name,
country_name
I want to get all target_screen_name from twitter_users_relationship that have matched target_country with u.country or utc.country_name
My query so far
SELECT u.screen_name,
u.country,
tf.target_screen_name,
tf.target_country,
ta.action_name,
ta.action_status,
utc.country_name
FROM users u
LEFT JOIN twitter_users_relationship tf
ON u.screen_name=tf.screen_name
LEFT JOIN user_twitter_action_map ta
ON u.screen_name=ta.screen_name
AND ta.action_name='follow'
AND ta.action_status='active'
LEFT JOIN user_targeted_countries utc
ON u.screen_name= utc.screen_name
WHERE u.status = 'active'
AND tf.follow_status = 'pending'
AND tf.target_country != ''
AND tf.target_country IS NOT NULL
AND ( utc.country_name=tf.target_country OR u.country=tf.target_country)
AND u.screen_name = 'my_screen_name';
But this query giving me duplicate record for each entry of countries in user_targeted_countries. If there are 3 counties in user_targeted_countries the it will return 3 duplicate records.
Please let me know what JOIN I need to use with user_targeted_countries to get desired results.
u.country can be different than countries in utc.country_name
UPDATE -
If I removes OR u.country=tf.target_country from the WHERE clause then I get all the matched target_screen_name without duplicate. But I am not sure how to get all those records also that matches with u.country=tf.target_country ?
Depends on the business logic required ..
First, regardless to the question, your query is wrong(Either the LEFT JOIN or the conditions) . When using LEFT JOIN , conditions on the right table should only be specified in the ON clause, which means you need to move all the conditions on tf. and utc. to the ON clause.
Secondly, you can use a GROUP BY clause and choose one of the utc.country_name (different answers will be if you want a specific one, if it doesn't matter, use MAX() on this column).
I have a select statement that uses inner joins on multiple tables, and I want to get COUNT() from one particular table, however my current statement is throwing an error:
Syntax error: unexpected 'COUNT' (count)
Helpful. I know. Gotta love MySQL's detailed and in-depth error messages.
Here is my select statement:
SELECT SE.SEId, SE.ParentME, SE.ParentSE, SE.Name, SE.Status, SE.Description,
UDC.UDCId, UDC.Code, UDC.Description,
TRM.COUNT(*)
FROM SubEquipment SE
INNER JOIN UserDefinedCode UDC ON UDC.ETId = SE.EquipmentType
INNER JOIN Terminal TRM ON TRM.SEId = SE.SEId
GROUP BY TRM.SEId
WHERE ParentME = #MEId;
What am I doing wrong? Is this possible?
You want to do the following:
SELECT SE.SEId, SE.ParentME, SE.ParentSE, SE.Name, SE.Status, SE.Description,
UDC.UDCId, UDC.Code, UDC.Description,
COUNT(DISTINCT TRM.SEID)
FROM SubEquipment SE
INNER JOIN UserDefinedCode UDC ON UDC.ETId = SE.EquipmentType
INNER JOIN Terminal TRM ON TRM.SEId = SE.SEId
WHERE ParentME = #MEId
GROUP BY 1,2,3,4,5,6,7,8,9
Because Count is an aggregate your single measures must be grouped. Plus the error you're seeing is because COUNT isn't a column in TRM. That's what it thinks you're asking for.
Try COUNT(DISTINCT [the TRM primary key field(s)]); it should count the distinct terminal "id" values, so even if the intermediate JOIN multiples the rows, you'll still get the number of terminals.
In addition to FirebladeDan's answer, (as he suggested) a subquery also cleaned this issue up:
SELECT DISTINCT SE.SEId, SE.ParentME, SE.ParentSE, SE.Name, SE.Status, SE.Description,
UDC.UDCId, UDC.Code, UDC.Description,
--Subquery to get the count
(SELECT COUNT(*) FROM Terminal WHERE TRM.SEId = SE.SEId) AS TerminalCount
FROM SubEquipment SE
INNER JOIN UserDefinedCode UDC ON UDC.ETId = SE.EquipmentType
LEFT JOIN Terminal TRM ON TRM.SEId = SE.SEId
WHERE ParentME = #MEId;
This got rid of the need for grouping the columns.
Subnote: I changed the INNER JOIN on the Terminal table to a LEFT JOIN, because if a SEId did not have any associated terminals, it would not return any information, which also called for a DISTINCT query.
SELECT distinct t1.vssyspackageid,CA.rAmount as Amount,Curr.vsShortCode AS Currency
from tblPrograms
INNER JOIN tblProgramsAndPackages ON tblPrograms.vsSysProgramId = tblProgramsAndPackages.vsSysProgramId
inner join tblPackages t1 on tblProgramsAndPackages.iPackageId=t1.iPackageId
right join tblPkgContractAwardDetails as CA on CA.iPackageId=t1.iPackageId
join tblCurrencies as Curr on CA.iCurrency =Curr.iCurrencyId
where tblPrograms.vsSysProgramId='JICA'
group by t1.vssyspackageid,CA.rAmount,Curr.vsShortCode
if which package assigned to Contractor Award Detail then it will show in one column.
Example: GWSSP/01,GWSSP/02 then after it it shows total package in next column.
I'm not sure exactly what you are wanting as your question is a little vague, but I'm guessing that you want a single row for the specified Package that will show the sum of the Amount column. This is what I can understand from your question anyway!
SELECT DISTINCT t1.vssyspackageid,
SUM(CA.rAmount) AS TotalAmount,
Curr.vsShortCode AS Currency
FROM tblPrograms
INNER JOIN tblProgramsAndPackages ON tblPrograms.vsSysProgramId =
tblProgramsAndPackages.vsSysProgramId
INNER JOIN tblPackages AS t1 ON tblProgramsAndPackages.iPackageId =
t1.iPackageId
RIGHT JOIN tblPkgContractAwardDetails AS CA ON CA.iPackageId =
t1.iPackageId
JOIN tblCurrencies AS Curr ON CA.iCurrency =
Curr.iCurrencyId
WHERE tblPrograms.vsSysProgramId = 'JICA'
AND t1.[YOUR_COLUMN_NAME_HERE] = 'GWSSP/01'
GROUP BY t1.vssyspackageid,
Curr.vsShortCode
Just a few things to note:
I don't know the column name in the tblPackages table that the values such as 'GWSSP/01' belongs, so I have left that for you to fill in.
You will still get multiple rows if there are multiple currencies for your package, you will have to remove the Curr.vsShortCode from your Select and Group By clauses if that is the case.
I also tided up your code a bit because it was quite messy and hard to understand as well as using multiple standards and short-cuts!
I was desperately trying harder and harder to get this thing done but didn`t yet succeed. I am getting repeated values when i run this query.
select
tbl_ShipmentStatus.ShipmentID
,Tbl_Contract.ContractID,
Tbl_Contract.KeyWinCountNumber,
Tbl_Item.ItemName,
Tbl_CountryFrom.CountryFromName,
Tbl_CountryTo.CountryToName,
Tbl_Brand.BrandName,
Tbl_Count.CountName,
Tbl_Seller.SellerName,
Tbl_Buyer.BuyerName,
Tbl_Contract.ContractNumber,
Tbl_Contract.ContractDate,
tbl_CountDetail.TotalQty,
tbl_CostUnit.CostUnitName,
tbl_Comission.Payment,
tbl_Port.PortName,
Tbl_Contract.Vans,
tbl_Comission.ComissionPay,
tbl_Comission.ComissionRcv,
tbl_CountDetail.UnitPrice,
tbl_Comission.ComissionRemarks,
tbl_CountDetail.Amount,
tbl_LCStatus.LCNumber,
tbl_ShipmentStatus.InvoiceNumber,
tbl_ShipmentStatus.InvoiceDate,
tbl_ShipmentStatus.BLNumber,
tbl_ShipmentStatus.BLDate,
tbl_ShipmentStatus.VesselName,
tbl_ShipmentStatus.DueDate
from tbl_ShipmentStatus
inner join tbl_LCStatus
on
tbl_LCStatus.LCID = tbl_ShipmentStatus.LCStatusID
inner join Tbl_Contract
on
tbl_LCStatus.ContractID = Tbl_Contract.ContractID
inner join Tbl_CountDetail
on Tbl_Contract.ContractID = Tbl_CountDetail.ContractId
inner join tbl_Comission
on
tbl_Comission.ContractID = Tbl_Contract.ContractID
inner join Tbl_Item
on
Tbl_Item.ItemID = Tbl_Contract.ItemID
inner join Tbl_Brand
on Tbl_Brand.BrandID = Tbl_Contract.BrandID
inner join Tbl_Buyer
on Tbl_Buyer.BuyerID = Tbl_Contract.BuyerID
inner join Tbl_Seller
on Tbl_Seller.SellerID = Tbl_Contract.SellerID
inner join Tbl_CountryFrom
on Tbl_CountryFrom.CountryFromID = Tbl_Contract.CountryFromID
inner join Tbl_CountryTo
on
Tbl_CountryTo.CountryToID = Tbl_Contract.CountryToID
inner join Tbl_Count
on
Tbl_Count.CountID = Tbl_CountDetail.CountId
inner join tbl_CostUnit
on tbl_Comission.CostUnitID = tbl_CostUnit.CostUnitID
inner join tbl_Port
on tbl_Port.PortID = tbl_Comission.PortID
where tbl_LCStatus.isDeleted = 0
and tbl_ShipmentStatus.isDeleted =0
and tbl_LCStatus.isDeleted = 0
and Tbl_CountDetail.isDeleted = 0
and Tbl_Contract.isDeleted = 0
and tbl_ShipmentStatus.LCStatusID = 5
I have also attached a picture of my result set of rows.
Any suggestions why this is happening would really be appreciable.
Result Set
Typically this happens when you have an implicit partial cross join (Cartesian product) between two of your tables. That's what it looks like to me here.
This happens most often when you have a many-to-many relationship. For example, if a single Album allows both multiple Artists and multiple Songs and the only relationship between Artists and Songs is Album, then there's essentially a many-to-many relationship between Artists and Songs. If you select from all three tables at once you're going to implicitly cross join Artists and Songs, and this may not be what you want.
Looking at your query, I see many-to-many between Tbl_CountDetail and tbl_Comission through Tbl_Contract. Try eliminating one of those joins to test to see if the behavior disappears.
Try using the DISTINCT keyword. It should solve your issue
Select DISTINCT ....
Wait as far as I can see your records are not duplicates.
HOWEVER
Notice the CountName column and Shipment ID column
The combination is unique for every row. Hence the values are unique as far as I can see. Try not selecting CountName.
Well if you have distinct rows its not a duplication problem. The issue is during the join a combination is occurring you don't want it to duplicating the results.
Either don't select CountName or you have a mistake in your data.
Only one of those rows should be true either 6 with Count2 or 6 with Count1. Likewise for 7. The fact that your getting both when your not supposed to indicates a logic mistake
I have this query:
SELECT
TA.id,
T.duration,
DATE_FORMAT(TA.startTime,'%H:%i') AS startTime,
TEI.displayname,
TA.threatment_id,
TE.employeeid,
TTS.appointment_date
FROM
tblEmployee AS TE
INNER Join tblEmployeeInfo AS TEI ON TEI.employeeinfoid = TE.employeeinfoid
LEFT OUTER Join tblAppointment AS TA ON TE.employeeid = TA.employee_id
LEFT OUTER Join tblThreatment AS T ON TA.threatment_id = T.threatmentid
LEFT OUTER Join tblAppointments AS TTS ON TTS.id = TA.appointments_id
AND TTS.appointment_date = '2009-10-19'
LEFT OUTER Join tblCustomerCard AS TCC ON TCC.customercardid = TTS.customercard_id
WHERE
TE.employeeid = 1
What I try to accomplish is to select an employee, if available, all appointments at a given date. When there aren't any appointments, it should at least give the information about the employee.
But right now, it just gives all appointments related to an employee, and passes null when the date doesn't match. Whats going wrong here?
Because you are doing a left OUTER join, it will only join those records that match the On condition and will attach Null when the condition is not met.
You will still get records for which there is no Appointments on that date.
If you did an INNER join, then if the On condition is not met, no record will be output. So you will not get any records for which there are no appointments on that date.
Ok, not sure what database you are on, but this would work on SQL server :
select * from tblEmployee TA
...
left join
( select * from tblAppointments ed where ed.appointment_date = '10/01/2008' ) TTS
on ON TTS.id = TA.appointments_id
Thats the vibe anyway! You might need to tinker a bit.. Im at work and cant get the whole thing going for ya! :)