2010-02-23 76 views
1

鑑於這些表T-SQL查詢來尋找失蹤的ID的日期範圍

table Channel 
-------------- 
ChannelID int IDENTITY 
<other irrelevant stuff> 

table Program 
-------------- 
ProgramID int IDENTITY 
ChannelID int 
AiringDate datetime 
<other irrelevant stuff> 

與此查詢

SELECT C.ChannelID, t.AiringDate 
FROM 
Channel C 
LEFT JOIN ( 
    SELECT distinct ChannelID 
    FROM Program 
    WHERE AiringDate = '2010-01-16' 
) p 
     ON p.ChannelID=C.ChannelID 
CROSS JOIN (
    SELECT AiringDate = '2010-01-16' 
) t 
WHERE C.ChannelID IN (1, 2, 74, 15, 906) /* the Channel table contains more channels than we are interested in */ 
    AND p.ChannelID IS NULL 

這將產生

ChannelID | AiringDate 
----------|----------- 
    2  | 2010-01-16 
    906 | 2010-01-16 

我怎樣才能將它修改爲接受日期範圍,以便結果將如

ChannelID | AiringDate 
----------|----------- 
    2  | 2010-01-16 
    906 | 2010-01-16 
    2  | 2010-01-17 
    906 | 2010-01-17 

如果沒有播出這兩個頻道節目的任何這兩天

這不返回行

SELECT C.ChannelID, t.AiringDate 
FROM 
Channel C 
LEFT JOIN ( 
    SELECT distinct ChannelID, AiringDate 
    FROM Program 
    WHERE AiringDate between '2010-01-16' and '2010-01-17' 
) p 
     ON p.ChannelID=C.ChannelID 
CROSS JOIN (
    SELECT AiringDate = '2010-01-16' 
    union 
    SELECT AiringDate = '2010-01-17' 
) t 
WHERE C.ChannelID IN (1, 2, 74, 15, 906) 
    AND p.ChannelID IS NULL 

CROSS JOIN是有點難看,這將是很好的擺脫它完全。請注意,第一個示例查詢有點複雜;對於單日我有一個簡單的辦法,只有輸出缺少ChannelIDs:

SELECT C.ChannelID 
FROM 
Channel C 
LEFT JOIN ( 
    SELECT distinct ChannelID 
    FROM Program 
    WHERE AiringDate = '2010-01-16' 
) p 
     ON p.ChannelID=C.ChannelID 
WHERE C.ChannelID IN (1, 2, 74, 15, 906) 
    AND p.ChannelID IS NULL 

回答

2

如果我理解正確的,這應該讓你的要求是什麼。

  • 將所有通道,每AiringDate
  • 選擇具有你所需要的日期之間AiringDates所有通道。
  • LEFT JOIN刪除所有通道已經有AiringDates

SQL語句

DECLARE @Channel TABLE (ChannelID INTEGER PRIMARY KEY) 
DECLARE @Program TABLE (ProgramID INTEGER PRIMARY KEY, ChannelID INTEGER, AiringDate DATETIME) 

INSERT INTO @Channel VALUES (1) -- Aired on 16 & 17 
INSERT INTO @Channel VALUES (2) -- Aired on 16 
INSERT INTO @Channel VALUES (3) -- Not Aired 

INSERT INTO @Program VALUES (1, 1, '01-16-2010') 
INSERT INTO @Program VALUES (2, 1, '01-17-2010') 
INSERT INTO @Program VALUES (3, 2, '01-16-2010') 


SELECT C.* 
FROM (
      SELECT C.ChannelID 
        , p.AiringDate 
      FROM @Channel C   
        CROSS JOIN ( 
        SELECT DISTINCT AiringDate 
        FROM @Program 
        WHERE AiringDate BETWEEN '01-16-2010' AND '01-17-2010' 
       ) p 
     ) c 
     LEFT OUTER JOIN (
      SELECT C.ChannelID, p.AiringDate 
      FROM @Channel C 
        INNER JOIN @Program p ON p.ChannelID = C.ChannelID 
      WHERE AiringDate BETWEEN '01-16-2010' AND '01-17-2010' 
     ) p ON p.ChannelID = C.ChannelID AND p.AiringDate = C.AiringDate 
WHERE p.ChannelID IS NULL AND p.AiringDate IS NULL 
+0

嗯,好險!不過,它只適用於16日沒有節目,17日沒有節目的節目。 我的例子可能缺乏。我想查找在某個日期範圍內沒有播放任何節目的頻道,並且還要返回可能已經播放的AiringDates。所以每個頻道和每個AiringDate都有一行。 – 2010-02-23 10:35:09

+0

實際上,除了你擺脫的醜陋的選擇/聯盟(這很好!)你的查詢做的和我原來的帖子中列出的第二個完全一樣。 如果我刪除我的 其中C.ChannelID IN(1,2,74,15,906) 規定(您的查詢省略),我得到相同的結果。執行計劃是相同的。 – 2010-02-23 10:47:19

+0

@ J F - 我已經添加了一些示例數據。對於這些數據,你期望輸出什麼?我的印象是它應該爲每個日期返回ChannelID 3。 – 2010-02-23 10:50:15