之間
粗略的解決方案是生成所有日子,然後聚合(計數)它們。它有效,但在記憶中很粗糙。如果這不是關鍵,這個解決方案肯定會奏效。另一種選擇是生成一個月份系列,並在有很多條件的情況下進行日差,如果性能很關鍵。
SELECT
dates.startdate::DATE,
dates.enddate::DATE,
to_char(days.s, 'Mon') AS mon,
to_char(days.s, 'YYYY') AS yr,
count(1) AS d
FROM dates
CROSS JOIN LATERAL (
SELECT * FROM generate_series(dates.startdate, dates.enddate, INTERVAL '1 day') s
) days
GROUP BY 1, 2, 3, 4
在任何情況下,這裏是第二個變體,通過幾個月循環,而不是(更快,更難理解):
SELECT
dates.startdate::DATE,
dates.enddate::DATE,
to_char(months.startdate, 'Mon') AS mon,
to_char(months.startdate, 'YYYY') AS yr,
least(
months.enddate::DATE - dates.startdate::DATE + 1, -- takes care of first month
dates.enddate::DATE - months.startdate::DATE + 1, -- takes care of last month
months.enddate::DATE - months.startdate::DATE + 1 -- takes care of full months from the middle of the intervals
) AS "days"
FROM dates
-- get months as first day in that month
CROSS JOIN LATERAL (
SELECT * FROM generate_series(
(to_char(dates.startdate, 'YYYY-MM-') || '01')::DATE,
(to_char(dates.enddate + INTERVAL '1 month', 'YYYY-MM-') || '01')::DATE - 1, INTERVAL '1 month') m
) days
-- get months as start date and end date
CROSS JOIN LATERAL (
SELECT
days.m::DATE AS startdate,
(days.m + INTERVAL '1 month')::DATE - 1 AS enddate
) months
應該是什麼 「月」 值如startdate = 2017-01-01和enddate = 2017-06-29?或者startdate = 2010-04-01和enddate = 2017-02-01的年份值? –
@a_horse_with_no_name第一個月值應爲一月,二月,三月,四月,五月,六月,在一個月的日子裏,包括開始日期和結束日期。而第二個日期年份分別爲2010,2011,2012,2013,2014,2015,2016,2017,分別爲日期和日期。 – dhS
請在添加要求之前添加評論。 – dhS