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

¿Cómo contar los días excepto los domingos entre dos fechas en Postgres?

Debe definir "entre dos fechas" más cerca. ¿Límite inferior y superior incluidos o excluidos? Una definición común sería incluir el inferior y excluir el límite superior de un intervalo. Además, defina el resultado como 0 cuando el límite superior e inferior sean idénticos. Esta definición coincide con la resta de fecha exactamente .

SELECT date '2017-01-31' - date '2017-01-01' AS days_between

Esta definición exacta es importante para excluir los domingos. Para la definición dada, un intervalo de Sun - Sun (1 semana después) no incluye el límite superior, por lo que solo hay 1 Domingo a restar.

interval in days  | sundays
0                 | 0
1-6               | 0 or 1
7                 | 1
8-13              | 1 or 2
14                | 2
...

Un intervalo de 7 días siempre incluye exactamente un domingo.

Podemos obtener el resultado mínimo con una simple división de enteros (días / 7 ), que trunca el resultado.

El domingo adicional para el resto de 1 a 6 días depende del primer día del intervalo. Si es domingo, bingo; si es un lunes, que mal. Etc. Podemos derivar una fórmula simple de esto:

SELECT days, sundays, days - sundays AS days_without_sundays
FROM  (
   SELECT z - a AS days
      , ((z - a) + EXTRACT(isodow FROM a)::int - 1 ) / 7 AS sundays
   FROM  (SELECT date '2017-01-02' AS a       -- your interval here
               , date '2017-01-30' AS z) tbl
   ) sub;

Funciona para cualquier intervalo dado.
Nota:isodow , no dow para EXTRACT() .

Para incluir el límite superior, simplemente reemplace z - a con (z - a) + 1 . (Funcionaría sin paréntesis, debido a la precedencia del operador, pero es mejor que quede claro).

La característica de rendimiento es O(1) (constante) en oposición a un agregado condicional sobre un conjunto generado con O(N) .

Relacionado:

  • ¿Cómo determino el último día del mes anterior usando PostgreSQL?
  • Calcular horas de trabajo entre 2 fechas en PostgreSQL