2017-02-09 66 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

相關問題