根据 SQL Server 2008 R2 中特定列中的模式更改对行进行分组

Posted

技术标签:

【中文标题】根据 SQL Server 2008 R2 中特定列中的模式更改对行进行分组【英文标题】:Group rows based upon a pattern change in specific columns in SQL Server 2008 R2 【发布时间】:2018-10-22 12:23:16 【问题描述】:

我将数据存储在 T1 表中。我想对行进行分组,以便特定行中的数据更改其值,并在数据模式的更改beforeafter中有行。例如,

表 T1:

ID    Operation    Worker

1         1           A
2         1           A
3         2           A
4         2           A
5         1           A
6         1           A
7         1           A

如何获取更改前后的行 ID,例如 ID 2、3、4、5?

编辑:我使用的是 SQL Server 2008 R2,所以滞后,领先功能不可用。

【问题讨论】:

【参考方案1】:

你可以试试这个。

DECLARE @T1 TABLE(ID INT, Operation INT,   Worker VARCHAR(5))
INSERT INTO @T1 VALUES
(1 ,1 ,'A'),
(2 ,1 ,'A'),
(3 ,2 ,'A'),
(4 ,2 ,'A'),
(5 ,1 ,'A'),
(6 ,1 ,'A'),
(7 ,1 ,'A')


;WITH T AS (
    SELECT *, ROW_NUMBER()OVER(ORDER BY ID) AS RN FROM @T1)
SELECT T.ID
     FROM T 
    LEFT JOIN T AS TP ON T.RN = TP.RN + 1
    LEFT JOIN T AS TN ON T.RN = TN.RN - 1
WHERE 
    T.Operation <> TP.Operation 
        OR T.Operation <> TN.Operation 

结果:

ID
-----------
2
3
4
5

【讨论】:

【参考方案2】:

如果没有lead()lag(),这会很痛苦。所以,让我们使用cross apply 来添加它们:

select t.*,
from t outer apply
     (select top (1) tprev.*
      from t tprev
      where tprev.id < t.id
      order by tprev.id desc
     ) tprev outer apply
     (select top (1) tnext.*
      from t tnext
      where tnext.id > t.id
      order by tnext.id asc
     ) tnext
where t.operation = 2 or
      (tprev.operation = 2 or tprev.operation is null) or
      (tnext.operation = 2 or tnext.operation is null)

【讨论】:

【参考方案3】:

我认为你需要lead() & lag()

select t.*
from (select t.*, 
             lag(operation, 1, operation) over (partition by worker order by id) as prev_op,
             lead(operation, 1, operation) over (partition by worker order by id) as next_op
      from tabke t
     ) t
where (operation <> prev_op) or (operation <> next_op);

编辑:对于旧版本,您可以使用apply

select t.*
from table t outer apply
     ( select top (1) prev_op.*
       from table prev_op
       where prev_op.id < t.id
       order by prev_op.id desc
     ) prev_op outer apply
     ( select top (1) next_op.*
       from table next_op
       where next_op.id > t.id
       order by prev_op.id asc
     ) next_op
where (t.operation <> prev_op.operation) or (t.operation <> next_op.operation);

【讨论】:

我希望但是 SQL 2008 R2 没有这些功能。

以上是关于根据 SQL Server 2008 R2 中特定列中的模式更改对行进行分组的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 2008 R2 中为特定数据库用户设置最大查询数

根据 SQL Server 2008R2 中表中的列获取计数

SQL Server 2008 R2 – 将多行减少为一行

SQL Server 2008 R2 根据WSDL访问WebService

如何在 SQL Server 2008 R2 中更改服务器排序规则

sql server 2008 R2 无法启动 提示 3417 错误