SQL - 搜索预订时间表,其中所有日期范围的预订都已取消

时间:2014-12-07 23:56:55

标签: sql

我正在查询预订系统,我需要确定所有预订时间表(代表定期预订),其中指定日期范围的所有预订都已取消。为什么以下查询会在 取消的指定日期范围内向我提供包含预订的预订时间表?

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

1 个答案:

答案 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。顺便说一句,您也可以将此查询短语作为聚合查询,但我将其保留为此格式,因为这似乎是您的意图。