¿Cómo puedo 'desagrupar' mis datos SQL sin utilizar la recursividad?
Tenemos una tabla que tiene datos en formato 'agregado' o 'acumulado'. Todas nuestras consultas y vistas almacenadas funcionan actualmente en el nivel "desenrollado" y, por lo tanto, unirse a esta consulta es particularmente problemático para valores únicos.
Estoy buscando formas de desagrupar los datos y he encontrado una manera de hacerlo usando un CTE con recursividad, pero esto me impide guardarlos como vista, ya que el servidor solo permitirá una recursividad de 100 y alterar esto, sería requieren la OPTION
declaración, que no será posible implementar en la aplicación que mira esto.
¿Existe otra forma de lograr este resultado y guardarlo en una vista para consultarlo?
A continuación se muestra un ejemplo de los datos:
+----+------------+------------+------+
| id | start date | end date | days |
+----+------------+------------+------+
| 1 | 2023-01-01 | 2023-01-05 | 5 |
| 1 | 2023-01-08 | 2023-01-10 | 3 |
| 2 | 2023-12-30 | 2023-12-31 | 2 |
| 3 | 2023-02-05 | 2023-02-07 | 3 |
+----+------------+------------+------+
Aquí está mi resultado deseado:
+----+------------+------+
| id | date | days |
+----+------------+------+
| 1 | 2023-01-01 | 1 |
| 1 | 2023-01-02 | 1 |
| 1 | 2023-01-03 | 1 |
| 1 | 2023-01-04 | 1 |
| 1 | 2023-01-05 | 1 |
| 1 | 2023-01-08 | 1 |
| 1 | 2023-01-09 | 1 |
| 1 | 2023-01-10 | 1 |
| 2 | 2023-12-30 | 1 |
| 2 | 2023-12-31 | 1 |
| 3 | 2023-02-05 | 1 |
| 3 | 2023-02-06 | 1 |
| 3 | 2023-02-07 | 1 |
+----+------------+------+
Gracias por cualquier ayuda.
En las versiones más recientes de SQL Server, puede utilizarlo GENERATE_SERIES
para dividir una sola fila en varias filas.
SELECT
t.id,
DATEADD(day, g.value, t.startDate) AS date,
1 AS days
FROM YourTable t
CROSS APPLY GENERATE_SERIES(0, DATEDIFF(day, t.startDate, t.endDate) g;
En versiones anteriores puedes usar una función de generación de números o una tabla de números.
Si generate_series
no es una opción, aquí creamos una tabla de números ad-hoc y realizamos una simpleJOIN
Select A.ID
,EffectiveDate = dateadd(DAY,N,[Start Date])
From YourTable A
Join ( Select Top 500 N=-1+Row_Number() Over (Order By 1/0) From master..spt_values n1 ) B
on B.N<Days
Nota: master..spt_values
se puede sustituir por cualquier mesa de tamaño adecuado. Además, puedes ajustar el top 500
tamaño a un tamaño más apropiado.