Sql 如何对这些数据进行分组,以便从每个组中提取特定行

Sql 如何对这些数据进行分组,以便从每个组中提取特定行,sql,sql-server-2008,group-by,Sql,Sql Server 2008,Group By,我的数据集如下所示。从这里,我想从每个组中选择第一行,其中PersonIDs状态已更改为与前一行不同的状态 例如,从这个数据集中,我想要第1、4、7和11行。 有什么帮助吗? 如果我做一个GROUPBY,它只是将所有新的和所有挂起的数据集中在两个组中 PersonID Status WhenChanged 101 New 27/01/2017 15:27 101 New 27/01/2017 16:40 101 New

我的数据集如下所示。从这里,我想从每个组中选择第一行,其中PersonIDs状态已更改为与前一行不同的状态

例如,从这个数据集中,我想要第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

这是一个尝试…使用CTE。由于您使用的日期为varchar格式或显示为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及以前的版本


这是一个尝试…使用CTE。由于您使用的日期为varchar格式或显示为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及以前的版本


非常感谢。不幸的是,在尝试运行它时,我意识到我只有sql server 2008,而滞后函数将无法工作。有没有其他方法可以不拖延地写这篇文章?@Tan我对2016年之前的文章进行了编辑。注意,您标记了SQL Server 2016,这就是我使用LAG的原因。请确保下次标记正确的版本。我已经改变了你的问题,以反映正确的标签。非常感谢。不幸的是,在尝试运行它时,我意识到我只有sql server 2008,而滞后函数将无法工作。有没有其他方法可以不拖延地写这篇文章?@Tan我对2016年之前的文章进行了编辑。注意,您标记了SQL Server 2016,这就是我使用LAG的原因。请确保下次标记正确的版本。我已更改您的问题以反映正确的标签。