Du skal definere "mellem to datoer" nærmere. Nedre og øvre grænse inkluderet eller ekskluderet? En almindelig definition ville være at inkludere den nederste og ekskluder den øvre grænse af et interval. Plus, definer resultatet som 0, når nedre og øvre grænse er identiske. Denne definition falder tilfældigvis sammen med datosubtraktion præcis .
SELECT date '2017-01-31' - date '2017-01-01' AS days_between
Denne nøjagtige definition er vigtig for at udelukke søndage. For den givne definition inkluderer et interval fra Sol - Sol (1 uge senere) ikke den øvre grænse, så der er kun 1 søndag at trække fra.
interval in days | sundays
0 | 0
1-6 | 0 or 1
7 | 1
8-13 | 1 or 2
14 | 2
...
Et interval på 7 dage inkluderer altid præcis én søndag.
Vi kan få minimumsresultatet med en almindelig heltalsdivision (dage / 7 ), som afkorter resultatet.
Den ekstra søndag i de resterende 1 - 6 dage afhænger af den første dag i intervallet. Hvis det er en søndag, bingo; hvis det er en mandag, ærgerligt. Osv. Vi kan udlede en simpel formel fra dette:
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;
Virker for alle givet interval.
Bemærk:isodow
, ikke dow
for EXTRACT()
.
At medtage den øvre grænse skal du bare erstatte z - a
med (z - a) + 1
. (Ville fungere uden parentes på grund af operatørens forrang, men det skal være klart.)
Ydeevnekarakteristika er O(1) (konstant) i modsætning til et betinget aggregat over et genereret sæt med O(N) .
Relateret:
- Hvordan bestemmer jeg den sidste dag i den foregående måned ved hjælp af PostgreSQL?
- Beregn arbejdstimer mellem 2 datoer i PostgreSQL