SQL基于次列去重SELECT结果:如何筛选无指定入住日期的房间号
现有SQL的问题原因
你当前写的查询是逐行匹配checkin != '2019-09'的条件,只要某一行的入住日期不是目标值,这一行就会被保留——哪怕同一个房间存在另一条目标日期的预订记录,最终DISTINCT去重后还是会把这个房间号查出来,这也是示例中101和102同时被返回的核心原因。
符合需求的查询写法
要实现「只要房间存在任意一条入住日期为指定dateX的记录,就将该房间从结果中整体排除」的逻辑,可以参考以下两种写法,对应示例数据执行后都会仅返回r_no=102:
写法1:NOT EXISTS 关联判断(推荐大表使用,性能更优)
SELECT DISTINCT r_no FROM roombooking rb WHERE NOT EXISTS ( SELECT 1 FROM roombooking rb_target WHERE rb_target.r_no = rb.r_no AND rb_target.checkin = '2019-09' )
逻辑说明:遍历每条预订记录对应的房间号,反向校验该房间是否存在任意一条入住日期为目标值的记录,只要匹配到就将整个房间排除,完全贴合你的筛选规则。
写法2:NOT IN 名单排除
SELECT DISTINCT r_no FROM roombooking WHERE r_no NOT IN ( SELECT r_no FROM roombooking WHERE checkin = '2019-09' )
逻辑说明:子查询先把所有存在过目标日期入住记录的房间号全部汇总成排除名单,外层查询仅返回不在这个名单内的房间号,结果和第一种写法完全一致。
注意:使用NOT IN写法时,要确保子查询返回的r_no字段不存在NULL值,否则会导致外层查询无有效返回结果,日常开发优先选NOT EXISTS写法更稳妥。
内容的提问来源于stack exchange,提问作者Spectromon
相关产品推荐
相关产品推荐

