Siempre que se pueda debemos evitar los bucles. Para el caso que comentas lo más sencillo sería tener una tabla con los inicio y fin de mes y cruzar con ella. Si no tenemos la tabla la podemos generar para la ocasión, por ejemplo una CTE con una consulta recursiva que nos devuelva las fechas. Algo así: WITH RangoMeses AS -- CTE con consulta recursiva para calcular las fechas ( SELECT FechaInicio = DATEFROMPARTS(2012, 1, 1), -- Fecha inicial del rango FechaFin = EOMONTH(DATEFROMPARTS(2012, 1, 1)) -- Fin del mes (último día) UNION ALL SELECT DATEADD(DAY, 1, FechaFin), -- Día siguiente al último día del mes anterior EOMONTH(DATEADD(DAY, 1, FechaFin)) -- Fin del mes actual FROM RangoMeses WHERE FechaFin < '20121231' -- Ajusta el rango hasta el año deseado ) SELECT FechaInicio, FechaFin, c = COUNT_BIG(*) FROM dbo.Votes AS v INNER JOIN RangoMeses AS r ON v.CreationDate >= r.FechaInicio AND v.CreationDate
Es exactamente lo mismo, siempre que uses la función en el lado del valor del filtro y no en el del campo de la tabla. Se calculará una vez y se usará para comparar con la tabla. No vas a notar la diferencia entre el calculo único de la última fecha de un mes a mano o con EOMONTH siempre que sea eso, solo una vez.
Espectacular, gracias por la explicación, buscaba un canal con estas características
Gracias a ti @Santymarchulo. Si tienes alguna sugerencia o tema del que te gustaría que hable me lo comentas.
Si agrupas por los meses de un año se debería hacer un bucle si se quiere usar la opción que comentas, ¿no? muy interesante el video. Un saludo.
Siempre que se pueda debemos evitar los bucles. Para el caso que comentas lo más sencillo sería tener una tabla con los inicio y fin de mes y cruzar con ella. Si no tenemos la tabla la podemos generar para la ocasión, por ejemplo una CTE con una consulta recursiva que nos devuelva las fechas.
Algo así:
WITH RangoMeses AS -- CTE con consulta recursiva para calcular las fechas
(
SELECT
FechaInicio = DATEFROMPARTS(2012, 1, 1), -- Fecha inicial del rango
FechaFin = EOMONTH(DATEFROMPARTS(2012, 1, 1)) -- Fin del mes (último día)
UNION ALL
SELECT
DATEADD(DAY, 1, FechaFin), -- Día siguiente al último día del mes anterior
EOMONTH(DATEADD(DAY, 1, FechaFin)) -- Fin del mes actual
FROM RangoMeses
WHERE FechaFin < '20121231' -- Ajusta el rango hasta el año deseado
)
SELECT
FechaInicio,
FechaFin,
c = COUNT_BIG(*)
FROM dbo.Votes AS v
INNER JOIN RangoMeses AS r
ON v.CreationDate >= r.FechaInicio
AND v.CreationDate
Y si utilizas la función eomonth para el parámetro final y omites el cálculo del último día, cuál sería el rendimiento
Es exactamente lo mismo, siempre que uses la función en el lado del valor del filtro y no en el del campo de la tabla. Se calculará una vez y se usará para comparar con la tabla. No vas a notar la diferencia entre el calculo único de la última fecha de un mes a mano o con EOMONTH siempre que sea eso, solo una vez.