2014-12-07 19 views
0

我正在查詢預訂系統,並且需要確定所有預訂時間表(表示經常性預訂),其中指定日期的所有預訂範圍已被取消。爲什麼以下查詢給我的預訂時間表包含在指定日期範圍內預訂已有被取消?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

我會使用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進行過濾。順便說一句,你也可以將這個查詢作爲一個聚合查詢來使用,但是我把它留在這種格式中,因爲這似乎是你的意圖。

+0

謝謝,這樣分解東西更清晰。我認爲問題在於我的最終'AND'是作爲'NOT EXISTS'條件的一部分。 – Izzy 2014-12-08 00:26:38

+0

@izzy。 。 。我對如何格式化查詢以避免這些類型的問題非常謹慎(儘管我認識到並非所有人都贊同我的美學觀點)。 – 2014-12-08 00:31:49