sql >> Base de Datos >  >> RDS >> PostgreSQL

Postgres:¿cómo devolver filas con 0 conteo de datos faltantes?

Solución adecuada

SELECT *
FROM  (
   SELECT day::date
   FROM   generate_series(timestamp '2007-12-01'
                        , timestamp '2008-12-01'
                        , interval  '1 month') day
   ) d
LEFT   JOIN (
   SELECT date_trunc('month', date_col)::date AS day
        , count(*) AS some_count
   FROM   tbl
   WHERE  date_col >= date '2007-12-01'
   AND    date_col <= date '2008-12-06'
-- AND    ... more conditions
   GROUP  BY 1
   ) t USING (day)
ORDER  BY day;
  • Usa LEFT JOIN , por supuesto.

  • generate_series() puede producir una tabla de marcas de tiempo sobre la marcha, y muy rápido.

  • Por lo general, es más rápido agregar antes Tú te unes. Recientemente proporcioné un caso de prueba en sqlfiddle.com en esta respuesta relacionada:

    • PostgreSQL:ordenar por matriz
  • Enviar la timestamp a date (::date ) para un formato básico. Para más uso to_char() .

  • GROUP BY 1 es una forma abreviada de sintaxis para hacer referencia a la primera columna de salida. Podría ser GROUP BY day también, pero eso podría entrar en conflicto con una columna existente del mismo nombre. O GROUP BY date_trunc('month', date_col)::date pero eso es demasiado largo para mi gusto.

  • Funciona con los argumentos de intervalo disponibles para date_trunc() .

  • count() nunca produce NULL (0 sin filas), pero el LEFT JOIN lo hace.
    Para devolver 0 en lugar de NULL en el exterior SELECT , usa COALESCE(some_count, 0) AS some_count . El manual.

  • Para una solución más genérica o intervalos de tiempo arbitrarios considere esta respuesta estrechamente relacionada:

    • La mejor manera de contar registros por intervalos de tiempo arbitrarios en Rails+Postgres