¿Cómo puedo 'desagrupar' mis datos SQL sin utilizar la recursividad?

Resuelto RazorKillBen asked hace 10 meses • 0 respuestas

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 OPTIONdeclaració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.

RazorKillBen avatar Feb 15 '24 22:02 RazorKillBen
Aceptado

En las versiones más recientes de SQL Server, puede utilizarlo GENERATE_SERIESpara 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.

Charlieface avatar Feb 15 '2024 16:02 Charlieface

Si generate_seriesno 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_valuesse puede sustituir por cualquier mesa de tamaño adecuado. Además, puedes ajustar el top 500tamaño a un tamaño más apropiado.

John Cappelletti avatar Feb 15 '2024 16:02 John Cappelletti