PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como contar dias exceto domingos entre duas datas no Postgres?


Você precisa definir "entre duas datas" mais perto. Limite inferior e superior incluído ou excluído? Uma definição comum seria incluir o menor e excluir o limite superior de um intervalo. Além disso, defina o resultado como 0 quando os limites inferior e superior forem idênticos. Esta definição coincide com a subtração da data exatamente .
SELECT date '2017-01-31' - date '2017-01-01' AS days_between

Esta definição exata é importante para excluir os domingos. Para a definição dada, um intervalo de Sun - Sun (1 semana depois) não inclui o limite superior, portanto, há apenas 1 Domingo para subtrair.
interval in days  | sundays
0                 | 0
1-6               | 0 or 1
7                 | 1
8-13              | 1 or 2
14                | 2
...

Um intervalo de 7 dias inclui sempre exatamente um domingo.

Podemos obter o resultado mínimo com uma divisão inteira simples (dias / 7 ), que trunca o resultado.

O domingo extra para o restante de 1 a 6 dias depende do primeiro dia do intervalo. Se for domingo, bingo; se for uma segunda-feira, muito ruim. Etc. Podemos derivar uma fórmula simples disso:
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 qualquer determinado intervalo.
Nota:isodow , não dow para EXTRACT() .

Para incluir o limite superior, basta substituir z - a com (z - a) + 1 . (Funcionaria sem parênteses, devido à precedência do operador, mas é melhor ficar claro.)

A característica de desempenho é O(1) (constante) em oposição a um agregado condicional sobre um conjunto gerado com O(N) .

Relacionado:
  • Como determino o último dia do mês anterior usando o PostgreSQL?
  • Calcular horas de trabalho entre 2 datas no PostgreSQL