我有预订可以提前预订。在预订当天,可以检出预留的设备。
我有两张桌子,预订和结账。预订有很多结账。
如何构建一个查询,该查询将返回没有相关结帐记录的特定日期的所有预订?
换句话说,来自预订的所有行,其中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,那很好。
答案 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
)