Php MYSQL查找外键不在相关表中的行
我可以提前预订。在预订当天,可以签出预订的设备 我有两张桌子,预订和退房。预订有很多退房 如何构造一个查询,返回特定日期的所有预订,这些预订没有关联的签出记录 换言之,保留的所有行中的reservation\u id列不包含保留的id 到目前为止,我最好的猜测是Php MYSQL查找外键不在相关表中的行,php,mysql,database,Php,Mysql,Database,我可以提前预订。在预订当天,可以签出预订的设备 我有两张桌子,预订和退房。预订有很多退房 如何构造一个查询,返回特定日期的所有预订,这些预订没有关联的签出记录 换言之,保留的所有行中的reservation\u id列不包含保留的id 到目前为止,我最好的猜测是 SELECT * FROM reservations WHERE reservations.id NOT IN (SELECT reservation_id FROM checkouts) 但结果是空的。这是桌子的大致形状 |res
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
注意:如果需要php,这很好。对于查询不返回任何行,最可能的解释是,
签出
中有行的保留id值为空。请考虑:
4 NOT IN (2,3,5,NULL,11)
在解释这一点时,空值被视为意味着“未知值是什么”。名单上有4个吗?答案(从SQL返回)基本上是“未知”4是否匹配列表中的“未知”值
如果这就是导致该行为的原因,您可以通过在子查询中包含WHERE reservation 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
)
这可能不是返回指定结果的最有效方法。反联接是返回此类结果的常见模式。在您的情况下,这将是一个外部联接,返回保留
中的所有行,以及签出
中的匹配行,然后在WHERE子句中使用谓词筛选出所有具有匹配的行,留给我们的是保留
中没有匹配的行
例如:
SELECT r.*
FROM reservations r
LEFT
JOIN checkouts c
ON c.reservation_id = r.reservation_id
WHERE c.reservation_id IS NULL
还可以使用相关子查询获得与不存在的等价的结果
SELECT r.*
FROM reservations r
WHERE NOT EXISTS ( SELECT 1
FROM checkouts c
WHERE c.reservation_id = r.reservation_id
)
您当前的查询似乎给出了所需的结果。查询完全正确。没有返回行的最可能解释是,签出
中至少有一行在保留id
列中有空值。如果是这种情况,则NOT IN
谓词的结果将为NULL,这意味着不会返回任何行。请参阅我的答案。保留id为空,因为某些项目是在没有保留的情况下签出的。我要核实一下,但我认为这就是答案。@crowhill:在没有事先预约的情况下,物品可以“退房”似乎是完全合理的。保留id列中的空值可以模拟“与保留没有关系”。(您刚刚被notin(NULL)
问题所困扰。“修复”确保列表中不存在空值。还有其他查询模式将返回相同的结果,如我的回答所示。这是最上面的示例。效果很好。谢谢!这个问题困扰了我一上午。@crowhill:只要有不在(列表)中
,您要确保该列表中不存在NULL,或者,如果您要在列表中允许NULL,您希望零行满足谓词。