sql-server - una - separar cadena delimitada por comas en sql server
Grupo TSQL por columna con valores mĂșltiples (2)
Tengo una tabla en SQLServer 2008r2 como a continuación.
Quiero seleccionar todos los registros donde la columna [Fg]
= 1 que consecutivamente por orden [Id]
conducen al valor 2 para cada [T_Id]
y [N_Id]
.
Puede haber casos donde el registro anterior a [Fg]
= 2 no es = 1
Puede haber cualquier cantidad de registros donde el valor de [Fg]
= 1 pero solo un registro donde [Fg]
= 2 para cada [T_Id]
y [N_Id]
.
Por lo tanto, para el ejemplo a continuación, deseo seleccionar registros con [Id]
s (4,5) y (7,8,9) y (19,20).
Cualquier registro para [T_Id]
3 y 4 está excluido.
Rendimiento esperado
Ejemplo de conjunto de datos
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)
No puede usar lag / lead porque comenzó en SQL 2012, tendrá que hacer algo como lo siguiente.
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
Se puede hacer fácilmente usando 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
La idea es simple La primera parte de la consulta obtiene todos valid
registros valid
con fg = 2
- válido significa que hay un registro antes de este con fg = 1
del mismo grupo.
Luego, en la parte recursiva estamos obteniendo todos los registros más pequeños que los iniciales, que tiene fg = 1
.