2013-08-02 37 views
0

ORIGINALSQL查詢來排除基於類型的記錄和日期

match_date actual_date  colA  type type_desc 
09/16/11 10/1/2011  ABC12345 A  TTT222 
09/16/11 10/8/2011  ABC12345 S  BADTYPE_123 
09/16/11 11/8/2011  ABC12345 A  YYY222 
09/16/11 11/8/2011  ABC12345 A  WWW333 
09/16/11 11/8/2011  ABC12345 B  YYY222 
09/16/11 11/8/2011  ABC12345 B  WWW333 
05/11/12 9/17/2012  ABC12345 B  ZZZ222 
05/11/12 9/17/2012  ABC12345 A  ZZZ222 
05/11/12 9/17/2012  MNO12345 B  CCC222 
05/11/12 9/17/2012  MNO12345 A  CCC222 
08/16/12 10/8/2011  MNO12345 S  BADTYPE_789 
08/16/12 10/9/2011  MNO12345 A  CCC111 
11/11/12 11/17/2012  MNO12345 S  BADTYPE_790 
12/01/12 9/17/2012  MNO12345 A  DDD222 
11/20/12 1/06/2013  XYZ98765 B  TST111 
11/20/12 1/06/2013  XYZ98765 A  TST111 
01/15/13 3/17/2013  XYZ98765 A  TST222 
05/11/13 6/15/2013  XYZ98765 B  TST111 
05/11/13 9/15/2013  XYZ98765 A  TST111 

對於每個給定match_date「組」(可樂和比賽日期,ABC12345和11年9月16日和ABC12345 05/11/12在第一「group」示例)中,如果記錄類型爲「S」且包含「BADTYPE *」作爲type_desc,我想排除/刪除給定「match_date組」的「BADTYPE」actual_date和下一個match_date之間的所有記錄。

如果給定的「match_date組」沒有「BADTYPE」記錄,則應該忽略它。如果給定match_date組的唯一記錄是BADTYPE記錄,則它將保持並繼續。

記錄到要刪除的紀錄

match_date actual_date  colA  type type_desc 
09/16/11 11/8/2011  ABC12345 A  YYY222 
09/16/11 11/8/2011  ABC12345 A  WWW333 
09/16/11 11/8/2011  ABC12345 B  YYY222 
09/16/11 11/8/2011  ABC12345 B  WWW333 
08/16/12 10/9/2011  MNO12345 A  CCC111 

最終結果中移除

match_date actual_date  colA  type type_desc 
09/16/11 10/1/2011  ABC12345 A  TTT222 
09/16/11 10/8/2011  ABC12345 S  BADTYPE_123 
05/11/12 9/17/2012  ABC12345 B  ZZZ222 
05/11/12 9/17/2012  ABC12345 A  ZZZ222 
05/11/12 9/17/2012  MNO12345 B  CCC222 
05/11/12 9/17/2012  MNO12345 A  CCC222 
08/16/12 10/8/2011  MNO12345 S  BADTYPE_789 
11/11/12 11/17/2012  MNO12345 S  BADTYPE_790 
12/01/12 9/17/2012  MNO12345 A  DDD222 
11/20/12 1/06/2013  XYZ98765 B  TST111 
11/20/12 1/06/2013  XYZ98765 A  TST111 
01/15/13 3/17/2013  XYZ98765 A  TST222 
05/11/13 6/15/2013  XYZ98765 B  TST111 
05/11/13 9/15/2013  XYZ98765 A  TST111 

希望我已經充分說明了正是我試圖做的。

任何幫助將不勝感激。

+0

你嘗試過什麼? – Nithesh

回答

0

我認爲最簡單快速的方法是使用窗口函數LEAD and LAG,但就您使用SQL Server 2008而言,這是不可能的。

在SQL Server 2008中,你可以使用outer apply - 通常,你需要是獲得由actual_date下降下令給「match_group」以前的記錄,刪除記錄,如果以前type_desc like 'BADTYPE%' and type = 'S'

當你決定你需要什麼,你可以很輕鬆錄製該算法到SQL,和感覺聲明語言的力量:

delete Table1 
from Table1 as T1 
    cross apply 
    (
     select top 1 T2.[type_desc], T2.[type] 
     from Table1 as T2 
     where T2.ColA = T1.ColA and T2.match_date = T1.match_date and T2.[actual_date] < T1.[actual_date] 
     order by T2.[actual_date] desc 
    ) as PR 
where PR.[type_desc] like 'BADTYPE%' and PR.[type] = 'S' 

你也可以查看SQL FIDDLE EXAMPLE,看看它是如何工作的

+0

這兩種解決方案似乎都在起作用......我們在講話時正在進行更多的測試。你們中的任何一個人能否推薦一本好書或網站來幫助我學習更高級的TSQL編程技巧? – user2162331

0

我建議你爲此使用遞歸查詢。
事情是這樣的:

SELECT *, 
     Row_number() 
     OVER ( 
      PARTITION BY COLA, MATCH_DATE 
      ORDER BY ACTUAL_DATE) RN 
INTO #TEMP1 
FROM TABLE1; 

WITH CTE 
    AS (SELECT *, 
       Cast(1 AS INT) AS flag 
     FROM #TEMP1 
     WHERE RN = 1 
     UNION ALL 
     SELECT t1.*, 
       CASE 
        WHEN T2.FLAG = 2 
         OR (t2.TYPE_DESC LIKE 'BADTYPE%' 
          AND t2.TYPE = 'S') THEN 2 
        ELSE 1 
       END flag 
     FROM #TEMP1 T1 
       INNER JOIN CTE T2 
         ON T1.COLA = T2.COLA 
          AND t1.MATCH_DATE = t2.MATCH_DATE 
          AND t1.RN = T2.RN + 1) 
SELECT [MATCH_DATE], 
     [ACTUAL_DATE], 
     [COLA], 
     [TYPE], 
     [TYPE_DESC] 
FROM CTE 
WHERE FLAG = 1 
ORDER BY COLA, 
      MATCH_DATE 

您可以在SQL Fiddle玩弄工作的例子。

祝你好運!

+0

這兩種解決方案似乎都在起作用......我們在說話時正在運行更多的測試。你們中的任何一個人能否推薦一本好書或網站來幫助我學習更高級的TSQL編程技巧? – user2162331

+0

這兩個解決方案都很好,第一個解決方案似乎可以用更少的代碼和更少的資源解決我的問題。謝謝! – user2162331