具有多个值的列的TSQL组

时间:2021-11-01 10:03:25

I have a table in SQLServer 2008r2 as below.

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

具有多个值的列的TSQL组

I want to select all the records where the [Fg] column = 1 that consecutively by [Id] order lead into value 2 for each [T_Id] and [N_Id] combination.

我想选择[Fg]列= 1连续按[Id]顺序导致每个[T_Id]和[N_Id]组合的值为2的所有记录。

There can be instances where record prior to [Fg] = 2 doesn't = 1

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

There can be any number of records where the value of [Fg] = 1 but only one record where [Fg] = 2 for each [T_Id] and [N_Id] combination.

可以存在任何数量的记录,其中[Fg]的值= 1,但是对于每个[T_Id]和[N_Id]组合,只有一个记录,其中[Fg] = 2。

So for the example below, I want to select records with [Id]s (4,5) and (7,8,9 )and (19,20).

因此,对于下面的示例,我想选择[Id] s(4,5)和(7,8,9)和(19,20)的记录。

Any records for [T_Id] 3 and 4 are excluded.

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

Expected output

预期产出

具有多个值的列的TSQL组

Example data set

示例数据集

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) 

2 个解决方案

#1


12  

It can be done easily using recursive CTE:

使用递归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

具有多个值的列的TSQL组

The idea is simple. The first part of the query gets all valid records with fg = 2 - valid means there is record before this one with fg = 1 from the same group.

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

Then in the recursive part we are getting all records smaller then initial ones, that has fg = 1.

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

#2


0  

You cant use lag/lead because it started in SQL 2012, you will need to do something like the below.

您无法使用滞后/潜在客户,因为它始于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

#1


12  

It can be done easily using recursive CTE:

使用递归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

具有多个值的列的TSQL组

The idea is simple. The first part of the query gets all valid records with fg = 2 - valid means there is record before this one with fg = 1 from the same group.

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

Then in the recursive part we are getting all records smaller then initial ones, that has fg = 1.

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

#2


0  

You cant use lag/lead because it started in SQL 2012, you will need to do something like the below.

您无法使用滞后/潜在客户,因为它始于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