2012-02-10 40 views
1

我們有一張表,其中包含訂閱產品的狀態更新。訂閱開始時,表中會插入一條記錄,並且訂閱結束時該記錄會更新爲結束日期。我們的系統之一(不知道哪一個系統)有時會在「同一天下落\添加」結束訂閱,然後再次開始(創建新記錄)。因此,即使沒有真正改變,相同的訂戶ID也會附加到多個記錄。不包括同一天下降添加,同時保留真實的開始和結束日期

實例數據會是這樣:

recID subID start   end  prodtype 
1  19 01/11/2001 01/15/2001 A 
2  19 01/15/2001 01/16/2001 A 
3  19 01/16/2001 01/20/2001 A 
4  19 01/30/2001 01/31/2001 A 

這傢伙開始在1/11和1/20上結束。記錄2和3被系統放入(當天下降添加,但不是真的)。記錄4是另一個訂閱19先生晚些時候開始。

我有一些代碼將嘗試解析每個不同的訂閱的第一個(真實的)記錄,但它不能找到真正的結束日期,而不使用max()和用戶分組。那當然會顯示兩個訂閱,1/11 - 1/31和1/30 - 1/31,這是錯誤的。

我撕裂了我的頭髮試圖解決這種模式下,以兩個記錄是這樣的:

subID start   end  prodtype 
19 01/11/2001 01/20/2001 A 
19 01/30/2001 01/31/2001 A 

這是Teradata的,但它只是ANSI SQL,我相信。

+0

存在使用會產生預期的結果窗口集合函數以及所述一個正確下文標識的溶液。如果我有時間,我也會盡力寫出來。 – 2012-02-13 15:01:41

回答

0

我相信這是ANSI SQL,但我只在SQL Server上測試過它。

基本上,查詢能夠獨立於彼此找到真正的開始日期和結束日期。然後將開始日期和結束日期相關聯,將開始日期與結束日期相比大於開始日期...,然後顯示最小結束日期。

SELECT 
    startDates.subId, 
    startDates.startDate, 
    MIN(endDates.endDate) AS endDate, 
    startDates.prodType 
FROM 
(
    SELECT 
     recID, subID, startDate, prodType 
    FROM yourTable s1 
    WHERE NOT EXISTS (
     SELECT 1 
     FROM yourTable s2 
     WHERE 
      s1.startDate = s2.endDate 
      AND s1.subId = s2.subId 
    ) 
) startDates JOIN 
(
    SELECT 
     recID, subID, endDate, prodType 
    FROM yourTable s1 
    WHERE NOT EXISTS (
     SELECT 1 
     FROM yourTable s2 
     WHERE 
      s1.endDate = s2.startDate 
      AND s1.subId = s2.subId 
    ) 
) endDates ON 
    startDates.subID = endDates.subID 
    AND startDates.startDate < endDates.endDate 
GROUP BY 
    startDates.subId, 
    startDates.startDate, 
    startDates.prodType 

Here is the query in action...

+0

這太神奇了。非常感謝!!!爲了能夠在合理的時間內運行(表格非常龐大),我必須使用計時器,所以我創建了一個包含在我的學習開始日期後開始或結束的任何記錄的送紙器表,然後使用您的代碼,然後在我的學習開始日期之前刪除任何顯示的內容。像冠軍一樣工作! – user548084 2012-02-10 22:02:45

0

您可以用代碼的實際結束日期這樣找到的所有記錄:

select t1.* 
from myTable t1 left outer join myTable t2 on 
t1.SubID = t2.SubID and 
t1.end = t2.start and t2.start is null 

您可以用類似的方式找到啓動記錄,當然。那麼也許你可以把它們拼湊在一起。也就是說,有時候會放棄所有處理select語句,並使用存儲過程,或將所有數據返回給客戶端並在那裏處理。

相關問題