2017-02-09 65 views
1

我拥有下面显示的数据集。因此,我想从每个组中选择第一行,其中PersonID的状态已更改为与先前状态不同的状态。如何对这些数据进行分组,以便从每个组中抽出特定行

例如,从这个数据集,我想第1,4,7和11行。
对此有什么帮助?
如果我做了一个GROUPBY,它只是将所有新建和所有挂起组合在一起。

PersonID Status WhenChanged 
101   New  27/01/2017 15:27 
101   New  27/01/2017 16:40 
101   New  27/01/2017 16:40 
101   Pending 27/01/2017 16:40 
101   Pending 27/01/2017 16:40 
101   Pending 27/01/2017 16:40 
101   New  31/01/2017 09:14 
101   New  31/01/2017 10:02 
101   New  31/01/2017 10:03 
101   New  31/01/2017 10:05 
101   Pending 03/02/2017 14:29 
101   Pending 03/02/2017 14:29 

回答

0

这是一个去...使用CTE。由于您使用的日期是以varchar格式显示或因此显示,所以排序不起作用。你可以将它转换成相同的,这将工作正常。

declare @table table (PersonID int, Status varchar(16), WhenChanged varchar(64)) 
insert into @table values 
(101,'New','27/01/2017 15:27'), 
(101,'New','27/01/2017 16:40'), 
(101,'New','27/01/2017 16:40'), 
(101,'Pending','27/01/2017 16:40'), 
(101,'Pending','27/01/2017 16:40'), 
(101,'Pending','27/01/2017 16:40'), 
(101,'New','31/01/2017 09:14'), 
(101,'New','31/01/2017 10:02'), 
(101,'New','31/01/2017 10:03'), 
(101,'New','31/01/2017 10:05'), 
(101,'Pending','03/02/2017 14:29'), 
(101,'Pending','03/02/2017 14:29') 

;with cte as(
    select 
     PersonID, 
     Status, 
     WhenChanged, 
     case when lag(Status) over (partition by PersonID order by convert(datetime,WhenChanged,103)) <> Status then 1 else 0 end as d 
    from 
     @table) 



select top 1 * 
from @table 
union 
select PersonID, 
     Status, 
     WhenChanged 
from cte 
where d=1 
order by WhenChanged 

SQL Server 2008和以前版本

declare @table table (PersonID int, Status varchar(16), WhenChanged varchar(64)) 
insert into @table values 
(101,'New','27/01/2017 15:27'), 
(101,'New','27/01/2017 16:40'), 
(101,'New','27/01/2017 16:40'), 
(101,'Pending','27/01/2017 16:40'), 
(101,'Pending','27/01/2017 16:40'), 
(101,'Pending','27/01/2017 16:40'), 
(101,'New','31/01/2017 09:14'), 
(101,'New','31/01/2017 10:02'), 
(101,'New','31/01/2017 10:03'), 
(101,'New','31/01/2017 10:05'), 
(101,'Pending','03/02/2017 14:29'), 
(101,'Pending','03/02/2017 14:29') 


;with cte as(
    select 
     PersonID, 
     Status, 
     convert(datetime,WhenChanged,103) as WhenChanged, 
     row_number() over (order by personID, convert(datetime,WhenChanged,103)) as RN 
    from 
     @table), 

cteResults as(
    select 
     PersonID, 
     Status, 
     WhenChanged 
    from 
     cte 
    where RN = 1 
    UNION 
    select 
     c.PersonID, 
     c.Status, 
     c.WhenChanged 
    from 
     cte c 
    inner join 
     cte c2 on c2.rn = (c.rn -1) and c2.status <> c.status) 

select * from cteResults order by WhenChanged 
+0

非常感谢这一点。不幸的是,当试图运行它时,我意识到我只有sql server 2008,而滞后函数不起作用。有没有另一种方式来写这没有滞后? – Tan

+0

@Tan我在2016年之前编辑了我的帖子。请注意,您标记了SQL Server 2016,这就是我使用'LAG()'的原因。请务必在下次标记正确的版本。我已更改您的问题以反映正确的标签。 – scsimon

相关问题