Он ведет себя совершенно правильно.
Это:
dateadd(month,
-6,
dateadd(day, -3, date('20180503'))
) AS "should be 31oct17"
говорит: «Дайте мне дату за 6 месяцев до даты, за 3 дня до 2018-05-03».
Дата, за 3 дня до 2018-05-03
: 2018-04-30
Дата за 6 месяцев до 2018-04-30
: 2017-10-30
Если вместо этого вы изменили две операции:
- Дата за 6 месяцев до
2018-05-03
: 2018-11-03
- Дата, за 3 дня до
2018-11-03
: 2018-10-31
(один день спустя)
Итак, проблема вызвана тем, что некоторые месяцы имеют 30 дней, а другие месяцы имеют 31 день.
Возможно, вы хотите " последний день месяца ". Это всегда трудно и смущает нас, людей, и лучше избегать этого. Если вам это действительно нужно, то проще всего получить, вычтя день из первого дня следующего месяца:
SELECT
dt,
(dt + '1 month'::interval - '1 day'::interval)::date
FROM (SELECT ('2018-01-01'::date + '1 month'::interval * generate_series(0,11))::date as dt)
возвращается:
2018-01-01 2018-01-31
2018-02-01 2018-02-28
2018-03-01 2018-03-31
2018-04-01 2018-04-30
2018-05-01 2018-05-31
2018-06-01 2018-06-30
2018-07-01 2018-07-31
2018-08-01 2018-08-31
2018-09-01 2018-09-30
2018-10-01 2018-10-31
2018-11-01 2018-11-30
2018-12-01 2018-12-31