我正在查询预订系统,我需要确定所有预订时间表(代表定期预订),其中指定日期范围的所有预订都已取消。为什么以下查询会在 取消的指定日期范围内向我提供包含预订的预订时间表?
SELECT DISTINCT b.BookingScheduleId FROM Booking b
WHERE b.CancellationStatus = 1
AND b.[Date] BETWEEN '01-Nov-14' AND '31-Dec-14'
AND NOT EXISTS (
SELECT * FROM Booking ref
WHERE ref.BookingScheduleId = b.BookingScheduleId
AND ref.[Date] BETWEEN '01-Nov-14' AND '31-Dec-14'
AND b.CancellationStatus = 0
)
AND b.BookingScheduleId IS NOT NULL
答案 0 :(得分:1)
我首先使用ANSI标准日期编写查询:
SELECT DISTINCT b.BookingScheduleId
FROM Booking b
WHERE b.CancellationStatus = 1 AND
b.[Date] BETWEEN '2014-01-14' AND '2014-12-31' AND
NOT EXISTS (SELECT 1
FROM Booking ref
WHERE ref.BookingScheduleId = b.BookingScheduleId AND
ref.[Date] BETWEEN '2014-01-14' AND '2014-12-31' AND
b.CancellationStatus = 0
-----------------------^
) AND
b.BookingScheduleId IS NOT NULL;
然后我会注意带下划线的部分并稍微改写一下查询:
SELECT s.BookingScheduleId
FROM (SELECT DISTINCT BookingScheduleId
FROM Booking b
WHERE b.CancellationStatus = 1 AND
b.[Date] BETWEEN '2014-01-14' AND '2014-12-31' AND
b.BookingScheduleId IS NOT NULL
) s
WHERE NOT EXISTS (SELECT 1
FROM Booking ref
WHERE ref.BookingScheduleId = s.BookingScheduleId AND
ref.[Date] BETWEEN '2014-01-14' AND '2014-12-31' AND
ref.CancellationStatus = 0
);
我更喜欢做过滤和不同的子查询。它可能可能更快(虽然我不知道没有查看执行计划或测量性能),但我更清楚,因为子查询获取候选计划而外部计划进行过滤使用not exists
。顺便说一句,您也可以将此查询短语作为聚合查询,但我将其保留为此格式,因为这似乎是您的意图。