2011-07-29 21 views
13

Necesito hacer una consulta y unirme a todos los días del año, pero en mi base de datos no hay una tabla de calendario.
Después de google-ing encontré generate_series() en PostgreSQL. ¿MySQL tiene algo similar?generate_series() equivalente en MySQL

Mi tabla real tiene algo como:

date  qty 
1-1-11 3 
1-1-11 4 
4-1-11 2 
6-1-11 5 

Pero mi consulta tiene que volver:

1-1-11 7 
2-1-11 0 
3-1-11 0 
4-1-11 2 
and so on .. 
+0

¿Por qué no puedes hacer esto en la capa lógica de tu aplicación? – Shef

+3

No es la solución "correcta" para hacer en la lógica de la aplicación. Es mejor, realmente mejor hacerlo a través de sql (si es posible). Si no es posible ... bien, lo haré en la lógica de mi aplicación ... – stighy

+0

@stighly: Bueno, puedes resolver la mitad del problema en MySQL. Es decir, puedes 'GROUP BY date' y' SUM (qty) qty', pero no recuerdo ninguna solución de la parte superior de mi cabeza para agregar filas para las secuencias faltantes. Es mejor hacerlo en la lógica de la aplicación, si una fecha tiene un valor de cantidad, muéstrela, de lo contrario muestre 0. – Shef

Respuesta

23

Esto es cómo lo hago. Se crea un rango de fechas de 2011-01-01 a 2011-12-31 :

select 
    date_format(
     adddate('2011-1-1', @num:[email protected]+1), 
     '%Y-%m-%d' 
    ) date 
from 
    any_table,  
    (select @num:=-1) num 
limit 
    365 

-- use limit 366 for leap years if you're putting this in production 

El único requisito es que el número de filas en any_table debe ser mayor o igual a la tamaño del rango necesario (> = 365 filas en este ejemplo). Lo más probable es que utilice esto como una subconsulta de toda su consulta, por lo que en su caso any_table puede ser una de las tablas que utiliza en esa consulta.

+2

Extremadamente raro, pero funciona como un encanto. Lo estoy usando totalmente. Mucho mejor que otros métodos que vi. –

+0

¿No se rompe esto durante los años bisiestos? – Milimetric

+0

@Milimetric No. Simplemente genera 365 días seguidos, pero es posible que necesite 'limit 366' para años bisiestos. – Karolis

3

versión mejorada de la solución de @Karolis asegura que funciona para cualquier año (incluyendo los años bisiestos):

 
select date from (
    select 
     date_format(
     adddate('2011-1-1', @num:[email protected]+1), 
     '%Y-%m-%d' 
    ) date 
    from 
     any_table, 
    (select @num:=-1) num 
    limit 
     366 
) as dt 
where year(date)=2011 
3

que estaba buscando a esta solución, pero sin la fecha "codificado", y vine-up con este válido para el año actual (ayudado desde este answers). Tenga en cuenta la

where year(date)=2011 

no es necesario ya que el selectivo ya filtrar la fecha. También de esta forma, no importa qué tabla (al menos como se indicó antes de que la tabla tenga al menos 366 filas) se ha utilizado, ya que la fecha se "calcula" en tiempo de ejecución.

select date from (
    select 
     date_format(
     adddate(MAKEDATE(year(now()),1), @num:[email protected]+1), 
     '%Y-%m-%d' 
    ) date 
    from 
     your_table, 
    (select @num:=-1) num 
    limit 
     366) as dt 
Cuestiones relacionadas