ORIGINAL
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“组”(colA和匹配日期,ABC12345和09/16/11以及ABC12345 05/11/12在第一个“组”示例中),如果记录是“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 :(得分: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上使用工作示例。
祝你好运!答案 1 :(得分: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以查看其工作原理