MYSQL查找外键不在相关表中的行

时间:2014-09-25 18:50:08

标签: php mysql database

我有预订可以提前预订。在预订当天,可以检出预留的设备。

我有两张桌子,预订和结账。预订有很多结账。

如何构建一个查询,该查询将返回没有相关结帐记录的特定日期的所有预订?

换句话说,来自预订的所有行,其中reservation_id列不包含预订的ID?

到目前为止,我最好的猜测是

SELECT * FROM reservations WHERE reservations.id NOT IN (SELECT reservation_id 
FROM checkouts)

但是这会返回空白。这里大概了解表格的样子

|reservations|  |checkouts         |
|id = 1      |  |reservation_id = 1|
|id = 2      |  |reservation_id = 2|
|id = 3      |  

我的结果应该是预约3。

P.S。如果需要php,那很好。

1 个答案:

答案 0 :(得分:2)

对于不返回任何行的查询,最可能的解释是checkouts中的行对于reservation_id具有NULL值。考虑一下:

4 NOT IN (2,3,5,NULL,11)

在解释这一点时,NULL值被视为“未知值是什么”。该列表中有4个吗?答案(从SQL返回)基本上是“未知的”4是否匹配列表中的“未知”值。

如果这是导致该行为的原因,您可以通过在子查询中包含WHERE reservation IS NOT NULL来“修复”当前查询。

SELECT r.* 
  FROM reservations r
 WHERE r.id NOT IN ( SELECT c.reservation_id 
                       FROM checkouts c
                      WHERE c.reservation_id IS NOT NULL
                   )

这可能不是返回指定结果的最有效方法。反连接是返回此类结果的常见模式。在您的情况下,这将是一个外部联接,以返回reservations中的所有行,以及来自checkouts的匹配行,然后返回WHERE子句中的谓词以过滤掉所有具有匹配,给我们留下reservations中没有匹配项的行。

例如:

SELECT r.*
  FROM reservations r
  LEFT
  JOIN checkouts c
    ON c.reservation_id = r.reservation_id
 WHERE c.reservation_id IS NULL

也可以使用带有相关子查询的NOT EXISTS获得等效结果。

SELECT r.*
  FROM reservations r
 WHERE NOT EXISTS ( SELECT 1
                      FROM checkouts c
                     WHERE c.reservation_id = r.reservation_id
                   )