sql server - values - Groupe TSQL par colonne avec plusieurs valeurs




sql server concatener les valeurs d'une colonne (2)

J'ai une table dans SQLServer 2008r2 comme ci-dessous.

Je veux sélectionner tous les enregistrements où la colonne [Fg] = 1 qui consécutivement par l'ordre [Id] mène à la valeur 2 pour chaque [T_Id] et [N_Id] .

Il peut y avoir des cas où l'enregistrement avant [Fg] = 2 ne l'est pas = 1

Il peut y avoir un nombre quelconque d'enregistrements où la valeur de [Fg] = 1 mais un seul enregistrement où [Fg] = 2 pour chaque [T_Id] et [N_Id] .

Donc, pour l'exemple ci-dessous, je veux sélectionner les enregistrements avec [Id] s (4,5) et (7,8,9) et (19,20).

Tous les enregistrements de [T_Id] 3 et 4 sont exclus.

Production attendue

Exemple de jeu de données

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) 

Cela peut être fait facilement en utilisant le 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

L'idée est simple. La première partie de la requête obtient tous valid enregistrements valid avec fg = 2 - signifie qu'il y a un enregistrement avant celui-ci avec fg = 1 du même groupe.

Ensuite, dans la partie récursive, nous obtenons tous les enregistrements plus petits que les premiers, avec fg = 1 .


Vous ne pouvez pas utiliser lag / lead car il a commencé dans SQL 2012, vous devrez faire quelque chose comme ci-dessous.

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




sql-server-2008-r2