La tabla en la que estoy trabajando tiene tres componentes:
- Una
ID
columna (clave primaria en otra tabla) - Algunas columnas de datos
- Fecha válida
from
/to
columnas.
Valores:
ID Data From To
1 a 2015-01-01 2015-01-05
1 a 2015-01-06 2015-01-10
1 b 2015-01-11 2015-01-15
1 a 2015-01-16 2015-01-20
2 c 2015-01-01 2015-01-05
2 c 2015-01-06 2015-01-10
La tabla se actualiza tomando "instantáneas" de otra fuente de datos en algunos intervalos y asignando fechas de validez a los registros. El problema es que estas instantáneas crean entradas duplicadas para registros (con diferentes fechas de validez) que no se modificaron en absoluto durante ese intervalo.
Quiero reducir el tamaño de la tabla buscando filas con fechas consecutivas y fusionándolas y asignándoles un único período de validez. Por ejemplo:
ID Data From To
1 a 2015-01-01 2015-01-10
1 b 2015-01-11 2015-01-15
1 a 2015-01-16 2015-01-20
2 c 2015-01-01 2015-01-10
La lógica que tengo actualmente es:
- Seleccione y ordene todas las filas por ID, campos de datos y campos 'válido desde' (para que estén en grupos de filas consecutivas).
- Use un cursor para comparar filas adyacentes para similitud.
- Si son iguales, combine filas y cambie el período de validez para incluir ambas filas.
Entiendo que los cursores son muy ineficientes (tengo un gran conjunto de datos), por lo que estoy buscando otros enfoques.
CREATE TABLE
declaración en la pregunta.Respuestas:
Si esta es solo una tabla de rangos consecutivos, su caso puede tratarse como un problema clásico de "brechas e islas", donde solo necesita aislar islas de rangos consecutivos y luego "condensarlas" tomando el mínimo
[from]
y El máximo[to]
por isla.Hay un método establecido para resolver esto usando dos llamadas ROW_NUMBER:
Esta consulta funcionará en una versión tan baja como SQL Server 2005.
fuente
Pude escribir una consulta para resolver este problema. Utiliza múltiples combinaciones y un bucle while para fusionar registros. Este código es compatible con SQL Server 2008 R2.
fuente
Solo para el caso en el que tiene intervalos de fechas no contiguos que, aunque consecutivos, deben permanecer separados, se me ocurrió esta solución:
Ver en SQL Fiddle
fuente
Escribí una consulta que parece funcionar. Utiliza expresiones de tabla comunes, declaraciones MERGE y funciones analíticas. Sin embargo, solo es compatible con SQL Server 2012+. Puede encontrar la esencia aquí: MergeRecordsByValidityDate.sql
fuente