2014-01-23 21 views
0

我有以下一组数据(采样给出)T-SQL中删除“复制/不感兴趣”的数据行

ID   Status Code Type  ModDate 
1234  1  1  AB   1995-04-01 
1234  1  1  CD   1998-08-31 
1234  1  1  AB   2003-08-31 
1234  1  NULL AB   2008-11-08 
1234  1  2  AB   2013-11-09 
1234  1  1  EF   2013-11-18 
... 

由于这些数据必须在某种时间表的观察,我想阅读只是从数据库以下,因为只有Type变化感兴趣:

ID   Status Code Type  ModDate 
1234  1  1  AB   1995-04-01 
1234  1  1  CD   1998-08-31 
1234  1  1  AB   2003-08-31 
1234  1  1  EF   2013-11-18 
... 

如何才能做到这一点?我试图对数据进行分区并给出一些行号,但是由于Type已分组,因此它会让我头疼。

SELECT 
    ID, Status, Code, Type, ModDate, 
    MIN(ModDate) OVER (PARTITION BY ID, Type) MinModDate, 
    MAX(ModDate) OVER (PARTITION BY ID, Type) MaxModDate, 
    ROW_NUMBER() OVER (PARTITION BY ID, Type ORDER BY ModDate) RowNumber 
FROM Data 

输出:

ID   Status Code Type  ModDate  MinModDate MaxModDate RowNumber 
1234  1  1  AB  1995-04-01 1995-04-01 2013-11-09 1 
1234  1  1  CD  1998-08-31 1998-08-31 1998-08-31 1 
1234  1  1  AB  2003-08-31 1995-04-01 2013-11-09 2 
1234  1  NULL AB  2008-11-08 1995-04-01 2013-11-09 3 
1234  1  2  AB  2013-11-09 1995-04-01 2013-11-09 4 
1234  1  1  EF  2013-11-18 2013-11-18 2013-11-18 1 
... 

输出预计:

ID   Status Code Type  ModDate  MinModDate MaxModDate RowNumber 
1234  1  1  AB  1995-04-01 1995-04-01 2013-11-09 1 
1234  1  1  CD  1998-08-31 1998-08-31 1998-08-31 1 
1234  1  1  AB  2003-08-31 1995-04-01 2013-11-09 1 
1234  1  NULL AB  2008-11-08 1995-04-01 2013-11-09 2 
1234  1  2  AB  2013-11-09 1995-04-01 2013-11-09 3 
1234  1  1  EF  2013-11-18 2013-11-18 2013-11-18 1 
... 

可以这样不使用游标容易实现?

+0

为什么预期输出第二,第三和第四行得到不1,2,3行号,如果PARTITION BY ID和TYPE? – Darka

+0

分区对'Type = AB'的所有行起作用,然后应用排序。这就是为什么第三行有'RowNumber = 2'而不是1,但这将是很好,因为我可以通过'RowNumber = 1'过滤 – Scoregraphic

+0

哦,你想要通过相同的订单放行号。得到它了。 – Darka

回答

1

,因为您使用2012那么这应该工作:

SELECT ID, Status, Code, Type, ModDate FROM 
(
SELECT 
    ID, Status, Code, Type, ModDate, 
    lag(type,1) OVER (ORDER BY ID, moddate) prevtype 
FROM data 
)t WHERE type<>ISNULL(prevtype,'') 
+0

现在第一行缺少'1234 1 1 AB 1995-04-01'。是否因为在这种情况下没有前一行? – Scoregraphic

+0

我在我的机器上测试过它,第一行就在那里。当没有前一行时,isnull(prevtype,'')应该保护。 – Jayvee

+0

注意到over(order by)现在是ID,ModDate – Jayvee

0

如果我理解正确的,你只需要包装你的原始SQL:

SELECT ID, Status, Code, Type, ModDate FROM 
(
SELECT 
    ID, Status, Code, Type, ModDate, 
    MIN(ModDate) OVER (PARTITION BY ID, Type) MinModDate, 
    MAX(ModDate) OVER (PARTITION BY ID, Type) MaxModDate, 
    ROW_NUMBER() OVER (PARTITION BY ID, Type ORDER BY ModDate) RowNumber 
FROM Data 
) t 
WHERE ModDate=MinModDate 
+0

使用此语句,数据为'1234 1 1 AB 2003-08-31'的行丢失 – Scoregraphic

1

分区中的数据是你想要的,你只需要通过类型做,因为感兴趣的唯一变化。您还需要添加ROW_NUMBER()函数以过滤所需的行。这是一个更新的查询。

;WITH cte AS 
(
    SELECT ID, [Status], Code, [Type], ModDate 
      ,rn = ROW_NUMBER() OVER (PARTITION BY ModDate ORDER BY ModDate) 
    FROM #data 
) 
SELECT ID, [Status], Code, [Type], ModDate 
FROM cte 
WHERE rn = 1 
ORDER BY ModDate, [Type] 
+0

使用此语句,数据为'1234 1 1 AB 2003-08-31'缺少 – Scoregraphic

+0

如果Type是您所感兴趣的是Type by Mod,那么为什么应该包含AB行?根据数据不清楚。 – mrrodd

+0

我想在时间线上的Type列中显示更改,当然可以将Type返回到过去已经存在的值,并且也可以使用相同的值再次保存记录。我试图忽略这些“相同的价值”。 – Scoregraphic