如何订购并为每个组选择前2名

时间:2016-09-29 15:30:46

标签: sql-server sql-server-2012

我有一张表格如下:

日志:

ID | GroupCode | Date | Description

因此ID对于表中的每个条目都是唯一的。 GroupCode是对条目进行分组的方式。

我想通过GroupCode和Date DESC对表进行排序。然后查看每个组的前2个条目,以确定每个组条目中的描述是否已从一个更改为另一个。

描述包含一些关键词,如“新”,“更新”,“删除”等。

完整描述总是各不相同,但我应该能够检查最新2个条目中的关键词每个组的描述并确定它是从新的更新到更新还是更新到新建或删除到新建等如果关键字在最近的2个条目中已从一个更改为另一个条目对该组的描述,则我的选择结果应包括该组以及关键字更改。例如,如果“描述”中的关键字是“新建”并转到“更新”,则结果应如下所示:

GroupCode | Change
 x      "from New to Update"

是否可以使用SQL查询,或者需要控制台应用程序来分析条目?

1 个答案:

答案 0 :(得分:0)

是的,这是可能的。首先使用ROW_NUMBER创建子查询以获取每个组的前2个条目。只需按GroupName分区,按日期排序并使用rownumbercolumn in (1,2)

获取行

然后,您可以使用LAG函数将当前行与前一行进行比较,以组成“更改”列。只需进行简单检查,确保不要比较来自不同组的行。

if exists(select * from [sys].[tables] where [name]='Logs' )
    drop table [Logs]

go

create table [Logs](
[Id] int identity not null primary key,
[GroupCode] varchar(50) not null,
[Date] date not null,
[Description] varchar(100) not null
)

insert [Logs]([GroupCode], [Date], [Description]) values('Group1', '2016-05-01', 'New')
insert [Logs]([GroupCode], [Date], [Description]) values('Group1', '2016-05-03', 'Update')
insert [Logs]([GroupCode], [Date], [Description]) values('Group1', '2016-05-04', 'Update')
insert [Logs]([GroupCode], [Date], [Description]) values('Group1', '2016-05-05', 'Delete')


insert [Logs]([GroupCode], [Date], [Description]) values('Group2', '2016-05-06', 'New')
insert [Logs]([GroupCode], [Date], [Description]) values('Group2', '2016-05-08', 'Update')
insert [Logs]([GroupCode], [Date], [Description]) values('Group2', '2016-05-15', 'Delete')
insert [Logs]([GroupCode], [Date], [Description]) values('Group2', '2016-05-20', 'New')


insert [Logs]([GroupCode], [Date], [Description]) values('Group3', '2016-05-21', 'New')
insert [Logs]([GroupCode], [Date], [Description]) values('Group3', '2016-06-03', 'Update')
insert [Logs]([GroupCode], [Date], [Description]) values('Group3', '2016-06-04', 'Update')
insert [Logs]([GroupCode], [Date], [Description]) values('Group3', '2016-06-05', 'Update')


select [GroupCode], [Change] from
(select *, 
case when LAG([Description]) OVER (ORDER BY [GroupCode] ASC, [Date] asc) = [Description] then 'No Change Visible' else
'From ' + LAG([Description]) OVER (ORDER BY [GroupCode] ASC, [Date] asc) + ' to ' + [Description] end [Change] from
(select [GroupCode], [Date], [Description], row_number() OVER(PARTITION BY [GroupCode] ORDER BY [Date] DESC) AS RowNumber
from Logs) Q1 -- Q1 query takes top 2 by date DESC for each group
where RowNumber in (1,2)) Q2 -- Q2 composes the change column by taking prev row value
where RowNumber = 1 -- here we just take last row fpr each group

结果是

GroupCode    Description
Group1       From Update to Delete
Group2       From Delete to New
Group3       No Change Visible

希望它有所帮助!