Information
Is there a way that I can retrieve two bits of information from another(same) table twice in one LEFT JOIN?
Attempt
Below is the SQL query I tried to put together in hopes would work. I hope you can see what I am trying to do from it.
SELECT cards.*, list.name FROM cards
LEFT JOIN list ON cards.main = list.id AS main_name
AND cards.enemy = list.id AS enemy_name
WHERE cards.id = 1
As you can see above I am trying to retrieve the names of two values cards.main AND cards.enemy from the list table.
Thank you, and any questions will be answered asap!
You have to join the list-table twice:
SELECT cards.*, main_name.name, enemy_name.name
FROM cards
LEFT JOIN list AS main_name ON cards.main = main_name.id
LEFT JOIN list AS enemy_name ON cards.enemy = enemy_name.id
WHERE cards.id = 1
Related
Hi dev's i'm new with "advanced" SQL I've try alone but I dont understand how to have the good result.
I'll try to take information from 4 tables in the same DB.
The first table items only have id and name.
2 others tables take the id from items to extract data.
The last tables takes one data from items_buy for print another data.
Lastly I concat 2 column from 2 DB for having a full information.
SELECT items.id, items.name, items_buy.item_cost AS item_cost, items_sales.item_price AS item_price, CONCAT(trader.name, planet.name) AS name_point
FROM ((((items
INNER JOIN items_buy ON items_buy.id = items.id)
INNER JOIN trader ON trader.id = items_buy.name_point)
INNER JOIN items_sales ON items_sales.id = items.id)
INNER JOIN planet ON planet.id = trader.planet)
WHERE items.id = 1;
I dont know how to make it work, she doesnt return an error in SQLyog or on my server.
In order:
ID / NAMEITEM / PRICE / SELLINGPRICE / NAME from concat
If you need more, some test data:
https://pastebin.com/6Bs4kbN9
I've run your test data and run your script against it. As I suggested in my commment, the problem is with the INNER JOIN you are using.
I am not sure whether you are aware, but when using an INNER JOIN, if the joined table is NULL for the current row, then nothing at all will be returned.
If you modify your query to use a LEFT JOIN, you will see the results that are available regardless of whether the joined tables are NULL or otherwise:
SELECT items.id, items.name, items_buy.item_cost AS item_cost, items_sales.item_price AS item_price, CONCAT(trader.name, planet.name) AS name_point
FROM ((((items
LEFT JOIN items_buy ON items_buy.id = items.id)
LEFT JOIN trader ON trader.id = items_buy.name_point)
LEFT JOIN items_sales ON items_sales.id = items.id)
LEFT JOIN planet ON planet.id = trader.planet)
WHERE items.id = 1;
This produces:
1 Agricium 24.45 25.6 NULL
1 Agricium 24.6 25.6 NULL
The problem in the case of your example is that the join to trader or planet has no result and therefore produces no output.
This is my structure of tables:
tables_structure
and there's tbl_owner, tbl_rooms and tbl_class.
How do I get id_class and class name from tbl_class.
The original source code is like this:
SELECT
clas.id_class,
clas.class_name
FROM
tbl_rooms AS room
LEFT JOIN tbl_class AS clas ON room.id_class = clas.id_class
LEFT JOIN tbl_owner AS own ON room.id_owner = own.id_owner
WHERE own.id_owner='1';
However, it did not work. Please help me?
SELECT
clas.id_class,
clas.class_name
FROM
tbl_rooms AS room
LEFT JOIN tbl_class AS clas ON room.id_class = clas.id_class
LEFT JOIN tbl_owner AS own ON room.id_owner = own.id_owner
WHERE own.id_owner='1';
Left Joins and wheres can be a little confusing.
Here you are asking for all rooms and if they have a class return it, it they have an owner return it. Which is done by the left join.
Then after getting that info, Your asking to filter the results by owner = 1
Given that there were left joins used to build this data, you have now said only show the results where both joins matched. Effectively turning the left join to an inner join.
I would take away the where clause and check the join conditions are producing results you expect first, then start to allow the where to narrow the result set.
The correct way to check if a left join is a condition is (own.id_owner='1') OR (own.id_owner is null)
That will bring back all owner = 1 and all unknown owners
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!
SELECT a.acikkapali,
b.onay, b.evrakno,
b.tarih,
a.kod,
d.ad,
a.note0,
a.sf_miktar,
a.sf_sf_unit,
a.rtalepedilentestarih,
c.evrakno
FROM stok47T a
LEFT JOIN stok47e b on a.evrakno = b.evrakno
LEFT JOIN stok46t1 c on a.evrakno = c.talepno
LEFT JOIN stok00 d on a.kod = d.kod
WHERE a.tarih = '2013/04/15'
I need to add two my tables into that script with right way that means If I mapped one of them then the normal row count increases this makes me crazy, I have been trying to solve that issue for a couple days but I had been fail many times.
I couldn't find a good mapped fields between stok47t and the others. But there are still a few columns(fields) matches for their types and data.
I need to listen ppl opinions and learns something.
Here is a big part of my query
If you are getting increase in row count then chances are it could be due to using LEFT JOIN. An INNER join might help (see http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html guidance)
SELECT a.acikkapali,
b.onay, b.evrakno,
b.tarih,
a.kod,
d.ad,
a.note0,
a.sf_miktar,
a.sf_sf_unit,
a.rtalepedilentestarih,
c.evrakno
FROM stok47T a
INNER JOIN stok47e b on a.evrakno = b.evrakno
INNER JOIN stok46t1 c on a.evrakno = c.talepno
INNER JOIN stok00 d on a.kod = d.kod
WHERE a.tarih = '2013/04/15'
However without understanding your data structure then there is a chance you might lose the information that you are after.
If you are getting multiple rows, it is probably due to a Cartesian product occurring in the joins. This is unrelated to the type of join (left/right/full/inner). It is based on the relationships between the tables. You have 1-N relationships along different dimensions.
Your conditions are:
FROM stok47T a
LEFT JOIN stok47e b on a.evrakno = b.evrakno
LEFT JOIN stok46t1 c on a.evrakno = c.talepno
LEFT JOIN stok00 d on a.kod = d.kod
I have no idea what these tables and fields mean. But, if you have a case where there is one row per evrakno in table stok47t, and there are two rows in table stok47e and three in table stok46t1, then you will get six rows in the output.
Without more information, it is impossible to tell you the best solution. One method is to summarize the tables. Another is to take the first or last corresponding row, by doing something like:
from stok47T a left join
(select s.*, row_number() over (partition by evrakno order by id desc) as seqnum
from stok47e s
) b
on a.evrakno = b.evrakno and b.seqnum = 1
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