Me gustan las CTEs (tabla de días)

Escrito por qwalgrande 09-10-2009 en General. Comentarios (2)

Pues sí, me gustan. En especial las recursivas, claro está. Se pueden hacer virguerías con ellas, hasta resolver sudokus (aunque eso quizá sea algo más complejo, si no te llamas Itzik Ben-Gan). Hoy os dejo un ejemplo sencillo, pero muy práctico, la obtención de una estructura temporal que contiene los días de un mes (un año o lo que quieras, que para eso están los parámetros que definen el rango).

 

declare

@fec_inicio DateTime,

@fec_fin DateTime

select @fec_inicio = '20091001', @fec_fin = '20091031'

;WITH FECHAS(fecha) AS (

SELECT @fec_inicio fecha

UNION ALL

SELECT DATEADD(day, 1, fecha) fecha

FROM FECHAS

WHERE fecha < @fec_fin

)

select fecha from FECHAS

OPTION (MaxRecursion 0);

 

Con lo que se obtiene lo siguiente:

 

fecha

-----------------------

2009-10-01 00:00:00.000

2009-10-02 00:00:00.000

2009-10-03 00:00:00.000

2009-10-04 00:00:00.000

2009-10-05 00:00:00.000

2009-10-06 00:00:00.000

2009-10-07 00:00:00.000

2009-10-08 00:00:00.000

2009-10-09 00:00:00.000

2009-10-10 00:00:00.000

2009-10-11 00:00:00.000

2009-10-12 00:00:00.000

2009-10-13 00:00:00.000

2009-10-14 00:00:00.000

2009-10-15 00:00:00.000

2009-10-16 00:00:00.000

2009-10-17 00:00:00.000

2009-10-18 00:00:00.000

2009-10-19 00:00:00.000

2009-10-20 00:00:00.000

2009-10-21 00:00:00.000

2009-10-22 00:00:00.000

2009-10-23 00:00:00.000

2009-10-24 00:00:00.000

2009-10-25 00:00:00.000

2009-10-26 00:00:00.000

2009-10-27 00:00:00.000

2009-10-28 00:00:00.000

2009-10-29 00:00:00.000

2009-10-30 00:00:00.000

2009-10-31 00:00:00.000

 

Y esto es muy útil si lo combinamos con otras cosas:

- Podemos cruzar esta tabla con la tabla de los días festivos y obtenemos una tabla de días laborables.

- Podemos cargar la dimensión tiempo de nuestro data warehouse.

- Podemos cruzarlo utlizarlo en un informe de ventas para mostrar un "0" para aquellos días en los que no se vendió nada, se rellenarían los huecos (en esta caso, sería ... fecha left join TablaVentas... para que en case de no haber ventas, el registro con ceros saliera igualmente).

- Podemos usarlo en un paquete de integration services para cargar una variable de tipo objeto, que luego usemos en un foreach loop container, lo que nos permitiría realizar la misma operación pero para un conjunto de días (puede que no carguemos todos los días, sólo aquellos de los que no se tengan datos).

 

Y un largo etcétera. Con pequeñas variaciones, podemos aplicar la misma lógica a otro montón de cosas, como crear una lista de minutos en un día, crear una lista de números consecutivos (ésta es más sencillita)... Las posibilidades dependerán ya de la habilidad de cada uno para manejarse con T-SQL.