How to group this data so I can pull out specific rows from each group

老子叫甜甜 提交于 2020-01-15 10:44:03

问题


I have the dataset shown below. From this, I want to select the first row from each group where the PersonIDs status has changed to a different status than the previous one.

For example, from this dataset, I would want the rows 1, 4, 7 and 11.
Any help on this?
If I do a GROUPBY, it just lumps together all New and all Pending in 2 groups.

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

回答1:


Here's a go at it...using a CTE. The ordering is off because your date you used was in a varchar format or displayed as such. You can convert it just the same and this will work fine.

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 and Previous Editions

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


来源:https://stackoverflow.com/questions/42142981/how-to-group-this-data-so-i-can-pull-out-specific-rows-from-each-group

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!