简体   繁体   English

具有内部联接条件的SQL查询

[英]SQL query with condition for an inner join

在此处输入图片说明

The context is this: a machine is in a location or in a position inside a location. 上下文是这样的:一台机器在某个位置或某个位置内的某个位置。 We have here 2 cases, the machine can have a value in the positionId or if the location hold only one machine, it has 0 as a value in positionsId. 这里有两种情况,一台机器可以在positionId中有一个值,或者,如果位置仅容纳一台机器,那么在positionId中它的值为0。 I wrote a query to return values for serialNo, name, address, dscription and identifier taking in consideration the cases of existiong or not a position: 我编写了一个查询以返回序列号,名称,地址,描述和标识符的值,并考虑到存在或不存在位置的情况:

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

The result is multiple lines of the same data. 结果是同一数据的多行。 Where am i doing it wrong? 我在哪里做错了?

Can you try the following: 您可以尝试以下方法:

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

I guess you're using MySQL. 我猜您正在使用MySQL。 As its documentation says, 如其文档所述

In MySQL, JOIN, CROSS JOIN, and INNER JOIN are syntactic equivalents (they can replace each other). 在MySQL中,JOIN,CROSS JOIN和INNER JOIN是语法等效项(它们可以相互替换)。 In standard SQL, they are not equivalent. 在标准SQL中,它们不是等效的。 INNER JOIN is used with an ON clause, CROSS JOIN is used otherwise. INNER JOIN与ON子句一起使用,否则使用CROSS JOIN。

It means your INNER JOIN positions is actually CROSS JOIN because there isn't ON clause. 这意味着您的INNER JOIN positions实际上是CROSS JOIN,因为这里没有ON子句。 This is why you get duplicated lines. 这就是为什么您会得到重复的行。 If you also select some column from positions table, you will see difference in it. 如果您还从positions表中选择某些列,则会看到其中的差异。

In addition to it, because a machine is in a location or in a position inside a location , you should not use INNER JOIN for location and positions . 除此之外,由于a machine is in a location or in a position inside a location ,因此不应将INNER JOIN用于locationpositions In your code, once location is inner joined, machines without locationId - FK are all lost. 在您的代码中,一旦location内部连接,没有locationId -FK的机器都将丢失。 If this is not what you expect, then both table should be joined by LEFT JOIN. 如果这不是您期望的,那么两个表都应由LEFT JOIN联接。

LEFT JOIN location 
ON machine.`locationId` = location.`id` 
LEFT JOIN positions
ON machine.`positionId` = positions.`id`

One more thing that looks weird for me is WHERE pos.locationId = machine.id . 在我看来,还有一件奇怪的事情是WHERE pos.locationId = machine.id This relationship is not described in the diagram you provided above. 您在上面提供的图中未描述此关系。 I guessed you might want to change it to WHERE pos.id = machine.positionId . 我猜想您可能想将其更改为WHERE pos.id = machine.positionId

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM