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)
Ответы
Ответ 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