TSQL 按具有多个值的列分组

TSQL Group by Column with Multiple Values

我在 SQLServer 2008r2 中有一个 table,如下所示。

我想 select [Fg] 列 = 1 的所有记录,按 [Id] 顺序连续为每个 [T_Id][N_Id]组合。

可能存在 [Fg] = 2 之前的记录不 = 1

的情况

[Fg] = 1 的记录可以有任意数量,但每个 [T_Id][N_Id] 组合只有一个 [Fg] = 2 的记录。

所以对于下面的例子,我想 select 记录 [Id]s (4,5) and (7,8,9 )and (19,20).

[T_Id]3 和 4 的任何记录都被排除。

预期输出

示例数据集

DECLARE @Data TABLE ( Id INT IDENTITY (1,1), T_Id INT, N_Id INT, Fg TINYINT )

INSERT INTO @Data
(T_Id, N_Id, Fg)
VALUES
(1, 2, 0), (1, 2, 1), (1, 2, 0), (1, 2, 1), (1, 2, 2), (2, 3, 0), (2, 3, 1), 
(2, 3, 1), (2, 3, 2), (3, 4, 0), (3, 4, 0), (3, 4, 0), (3, 4, 2), (4, 5, 0), 
(4, 5, 1), (4, 5, 0), (4, 5, 2), (5, 7, 0), (5, 7, 1), (5, 7, 2) 

使用recursive CTE可以轻松完成:

WITH DataSource AS
(
    SELECT DS1.*
    FROM @Data DS1
    INNER JOIN @Data DS2
        ON DS1.[T_Id] = DS2.[T_Id]
        AND DS1.[N_Id] = DS2.[N_Id]
        AND DS1.[Id] = DS2.[Id] + 1
        AND DS1.[Fg] = 2
        AND DS2.[Fg] = 1
    UNION ALL
    SELECT DS1.*
    FROM @Data DS1
    INNER JOIN DataSource DS2
        ON DS1.[T_Id] = DS2.[T_Id]
        AND DS1.[N_Id] = DS2.[N_Id]
        AND DS1.[Id] = DS2.[Id] - 1
        AND DS1.[Fg] = 1
)
SELECT *
FROM DataSource
ORDER BY Id

这个想法很简单。查询的第一部分获取所有 valid 条带 fg = 2 的记录 - 有效意味着在此之前有来自同一组的带 fg = 1 的记录。

然后在递归部分,我们得到的所有记录都小于初始记录,即fg = 1

您不能使用 lag/lead,因为它开始于 SQL 2012 年,您将需要执行如下操作。

SELECT  fg - (
        SELECT  TOP 1 fg
        FROM    table m2
        WHERE   m2.fg = m1.fg-1 OR (m2.fg = m1.fg AND m2.id < m1.id)
        ORDER BY 
                fg, id
        )
FROM table m1
ORDER BY
      fg, id