我得到了架构:
BOOKING (hotelNo, guestNo, dateFrom, dateTo)
来宾(guestNo,guestName,guestAddress)
我要求制定以下查询:列出与名字“Peter”相关的客人号码,这些客人号码在不使用显式或隐式连接的情况下进行了未知 dateTo 的预订。
我尝试的查询是:
(select guestNo from GUEST where guestName LIKE 'Peter')
INTERSECT ALL
(SELECT guestNo FROM BOOKING WHERE dateTo IS NULL);
但这不会返回每个 guestNo 最多 1 个条目的重复项,如小提琴中所示,返回值应该是 (1,1) 而不是 (1)。我考虑过使用 UNION,但是如果 dateTo 为 NULL 或 name 是 Peter,这将返回 guestNo,即这两个条件可能不一定成立。
数据库小提琴:https ://www.db-fiddle.com/f/tpzgVMwkQGAHBFxyMkyJvj/17
你们有什么建议吗?
在从英语到 SQL 的几乎字面翻译中,我会编写如下查询:
NB Postgres 不像其他一些 DBMS 不需要在 select 子句中有任何列!这在此处的子选择中是理想的,因为我们只对记录的存在感兴趣,而不对它的值感兴趣)。
见https://www.db-fiddle.com/f/tpzgVMwkQGAHBFxyMkyJvj/17
所有这些查询都将返回 1、1 并优化到相同的计划(针对您的模式和数据):
因为
guest.guestNo
是主键,所以这是相同的结果和相同的计划,带有连接的查询将优化为: