Вам нужно определить "между двумя датами" более близко. Нижняя и верхняя граница включены или исключены? Общее определение будет состоять из включает нижний и исключить верхний предел интервала. Кроме того, определить результат как 0, когда нижняя и верхняя границы идентичны. Это определение совпадает с вычитанием даты точно.
SELECT date '2017-01-31' - date '2017-01-01' AS days_between
Это точное определение важно для исключения воскресений. Для данного определения интервал от Sun-Sun (1 неделя спустя) не включает верхнюю границу, поэтому есть только Воскресенье для вычитания.
interval in days | sundays
0 | 0
1-6 | 0 or 1
7 | 1
8-13 | 1 or 2
14 | 2
...
Интервал 7 дней всегда включает ровно одно воскресенье.
Мы можем получить минимальный результат с помощью простого целочисленного деления (дней/7), который усекает результат.
Дополнительное воскресенье в течение 1 - 6 дней зависит от первого дня интервала. Если это воскресенье, бинго; если это понедельник, слишком плохо. И т.д. Мы можем получить простую формулу из этого:
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;
Работы для любого данного интервала.
Примечание: isodow
, not dow
for EXTRACT()
.
Для включает верхней границы, просто замените z - a
с (z - a) + 1
. (Будет работать без скобок, из-за приоритета операторов, но лучше быть ясно.)
Эксплуатационная характеристика является O (1) (константа), в отличие от условной совокупности более сгенерированного набора с O (N).
Похожие:
Unrelated, но: 'date_part ('день', возраст ('2017-01-31', '2017-01-01')) 'дает неверный результат, если« возраст »больше месяца. например 'date_part ('день', возраст ('2016-02-28', '2016-01-01'))' вернет 27, хотя должно быть 58. Если вы хотите количество дней между двумя датами, просто вычтите их : 'date '2017-01-31' - date '2017-01-01'' –
Спасибо @a_horse_with_no_name ... будет использовать это – Mani