Подтвердить что ты не робот

TSQL Group по столбцу с несколькими значениями

У меня есть таблица в SQLServer 2008r2, как показано ниже.

примерный набор данных

Я хочу выбрать все записи, в которых столбец [Fg]= 1, который последовательно ведет строку [Id], в значение 2 для каждой комбинации [T_Id] и [N_Id].

Могут быть случаи, когда запись до [Fg]= 2 не = 1

Может быть любое количество записей, где значение [Fg]= 1, но только одна запись, где [Fg]= 2 для каждой комбинации [T_Id] и [N_Id].

Итак, для примера ниже я хочу выбрать записи с [Id] (4,5) и (7,8,9) и (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) 
4b9b3361

Ответ 1

Это можно сделать легко, используя 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 - valid означает, что перед этой записью есть запись с fg = 1 из той же группы.

Тогда в рекурсивной части мы получаем все записи меньшими, чем начальные, которые имеют fg = 1.

Ответ 2

Вы не можете использовать 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