[英]SQL query with condition for an inner join
上下文是這樣的:一台機器在某個位置或某個位置內的某個位置。 這里有兩種情況,一台機器可以在positionId中有一個值,或者,如果位置僅容納一台機器,那么在positionId中它的值為0。 我編寫了一個查詢以返回序列號,名稱,地址,描述和標識符的值,並考慮到存在或不存在位置的情況:
SELECT machine.`serialNumber`, location.`name`, location.`address`, product.`identifier`,
(CASE WHEN EXISTS(SELECT `description`
FROM `positions` AS pos
WHERE pos.`locationId` = `machine`.`id`)
THEN `description`
ELSE 0
END) AS existPos
FROM machine
INNER JOIN location
ON machine.`locationId` = location.`id`
INNER JOIN positions
INNER JOIN product
ON machine.`id` = product.`machineId`
WHERE machine.`id` = 5
結果是同一數據的多行。 我在哪里做錯了?
您可以嘗試以下方法:
SELECT
machine.`serialNumber`,
location.`name`,
location.`address`,
product.`identifier`,
(CASE WHEN positions.Id is not null
THEN `description`
ELSE 0
END) AS existPos
FROM
machine
INNER JOIN
location
ON machine.`locationId` = location.`id`
LEFT JOIN
positions
on positions.`Id` = machine.`positionId`
INNER JOIN
product
ON machine.`id` = product.`machineId`
WHERE machine.`id` = 5
我猜您正在使用MySQL。 如其文檔所述 ,
在MySQL中,JOIN,CROSS JOIN和INNER JOIN是語法等效項(它們可以相互替換)。 在標准SQL中,它們不是等效的。 INNER JOIN與ON子句一起使用,否則使用CROSS JOIN。
這意味着您的INNER JOIN positions
實際上是CROSS JOIN,因為這里沒有ON子句。 這就是為什么您會得到重復的行。 如果您還從positions
表中選擇某些列,則會看到其中的差異。
除此之外,由於a machine is in a location or in a position inside a location
,因此不應將INNER JOIN用於location
和positions
。 在您的代碼中,一旦location
內部連接,沒有locationId
-FK的機器都將丟失。 如果這不是您期望的,那么兩個表都應由LEFT JOIN聯接。
LEFT JOIN location
ON machine.`locationId` = location.`id`
LEFT JOIN positions
ON machine.`positionId` = positions.`id`
在我看來,還有一件奇怪的事情是WHERE pos.locationId = machine.id
。 您在上面提供的圖中未描述此關系。 我猜想您可能想將其更改為WHERE pos.id = machine.positionId
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.