Du måste definiera "mellan två datum" närmare. Nedre och övre gräns inkluderad eller utesluten? En vanlig definition skulle vara att inkludera den lägre och uteslut den övre gränsen för ett intervall. Definiera dessutom resultatet som 0 när den nedre och övre gränsen är identiska. Denna definition råkar sammanfalla med datumsubtraktion exakt .
SELECT date '2017-01-31' - date '2017-01-01' AS days_between
Denna exakta definition är viktig för att utesluta söndagar. För den givna definitionen inkluderar inte ett intervall från Sun - Sun (1 vecka senare) den övre gränsen, så det finns bara 1 Söndag att subtrahera.
interval in days | sundays
0 | 0
1-6 | 0 or 1
7 | 1
8-13 | 1 or 2
14 | 2
...
Ett intervall på 7 dagar inkluderar alltid exakt en söndag.
Vi kan få det lägsta resultatet med en vanlig heltalsdivision (dagar / 7 ), vilket trunkerar resultatet.
Den extra söndagen för resten av 1 - 6 dagar beror på intervallets första dag. Om det är en söndag, bingo; om det är en måndag, synd. Etc. Vi kan härleda en enkel formel från detta:
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;
Fungerar för alla givet intervall.
Obs:isodow
, inte dow
för EXTRACT()
.
Att inkludera den övre gränsen, ersätt bara z - a
med (z - a) + 1
. (Skulle fungera utan parentes, på grund av operatörsföreträde, men det är bättre att vara tydlig.)
Prestandakaraktäristiken är O(1) (konstant) i motsats till ett villkorligt aggregat över en genererad uppsättning med O(N) .
Relaterat:
- Hur bestämmer jag den sista dagen i föregående månad med PostgreSQL?
- Beräkna arbetstid mellan 2 datum i PostgreSQL