Devi definire "tra due date" più strettamente. Limite inferiore e superiore inclusi o esclusi? Una definizione comune sarebbe includere quello inferiore ed escludi il limite superiore di un intervallo. Inoltre, definisci il risultato come 0 quando il limite inferiore e superiore sono identici. Questa definizione coincide con la sottrazione della data esattamente .
SELECT date '2017-01-31' - date '2017-01-01' AS days_between
Questa definizione esatta è importante per escludere la domenica. Per la definizione data un intervallo da Sole - Sole (1 settimana dopo) non include il limite superiore, quindi c'è solo 1 Domenica da sottrarre.
interval in days | sundays
0 | 0
1-6 | 0 or 1
7 | 1
8-13 | 1 or 2
14 | 2
...
Un intervallo di 7 giorni include sempre esattamente una domenica.
Possiamo ottenere il risultato minimo con una semplice divisione intera (giorni / 7 ), che tronca il risultato.
La domenica extra per i restanti 1 - 6 giorni dipende dal primo giorno dell'intervallo. Se è domenica, bingo; se è lunedì, peccato. Ecc. Possiamo ricavare una semplice formula da questo:
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;
Funziona per qualsiasi dato intervallo.
Nota:isodow
, non dow
per EXTRACT()
.
Per includere il limite superiore, sostituisci semplicemente z - a
con (z - a) + 1
. (Funzionerebbe senza parentesi, a causa della precedenza dell'operatore, ma è meglio essere chiari.)
La caratteristica delle prestazioni è O(1) (costante) rispetto a un aggregato condizionale su un insieme generato con O(N) .
Correlati:
- Come faccio a determinare l'ultimo giorno del mese precedente utilizzando PostgreSQL?
- Calcola le ore di lavoro tra 2 date in PostgreSQL