postgresql daysdiff在按月份分组的两个日期之间
我有一个带有日期列(开始日期、结束日期)的表,我想计算这些日期之间的差异,并按月份分组 我可以在几天内得到datediff,但我不知道如何在一个月内将其分组,有什么建议吗postgresql daysdiff在按月份分组的两个日期之间,postgresql,Postgresql,我有一个带有日期列(开始日期、结束日期)的表,我想计算这些日期之间的差异,并按月份分组 我可以在几天内得到datediff,但我不知道如何在一个月内将其分组,有什么建议吗 Table: id Start_date End_date days 1234 2014-06-03 2014-07-05 32 12345 2014-02-02 2014-05-10 97 Expected results: month diff
Table:
id Start_date End_date days
1234 2014-06-03 2014-07-05 32
12345 2014-02-02 2014-05-10 97
Expected results:
month diff_days
2 26
3 30
4 31
5 10
6 27
7 5
我认为你们的预期产量有点低。你可能想再检查一遍 我自己使用日历表,但这个查询使用CTE和日期算法。避免硬编码日期“2014-01-01”和365天的间隔很简单,但这会使查询更难阅读,所以我直接使用了这些值
with your_data as (
select date '2014-06-03' as start_date, date '2014-07-05' as end_date union all
select '2014-02-02', '2014-05-10'
), calendar as (
select date '2014-01-01' + (n || ' days')::interval calendar_date
from generate_series(0, 365) n
)
select extract (month from calendar_date) calendar_month, count(*) from calendar
inner join your_data on calendar.calendar_date between start_date and end_date
group by calendar_month
order by calendar_month;
谢谢你,它成功了。关于不同年份的分组,我有一个很好的观点,我目前正在使用一个case语句只显示当前年份的数据(日期为“2014-01-01”+(n | | |“days”)::interval<“2014-12-31”然后date“2014-01-01”+(n | |“days”)::interval END)日历日期。这几乎仅限于今年,我确实有截止到2015年的日期,知道如何在2014年的几个月里提取和分组这些数据吗?太棒了。非常感谢你,迈克!! calendar_month count -- 2 27 3 31 4 30 5 10 6 28 7 5
with your_data as (
select date '2014-06-03' as start_date, date '2014-07-05' as end_date union all
select '2014-02-02', '2014-05-10'
), calendar as (
select date '2014-01-01' + (n || ' days')::interval calendar_date
from generate_series(0, 700) n
)
select extract (year from calendar_date) calendar_year, extract (month from calendar_date) calendar_month, count(*) from calendar
inner join your_data on calendar.calendar_date between start_date and end_date
where calendar_date between '2014-01-01' and '2014-12-31'
group by calendar_year, calendar_month
order by calendar_year, calendar_month;
with min_max as (
select min(start_date) as start_date, max(end_date) as end_date
from t
), g as (
select daterange(d::date, (d + interval '1 month')::date, '[)') as r
from generate_series(
(select date_trunc('month', start_date) from min_max),
(select end_date from min_max),
'1 month'
) g(d)
)
select *
from (
select
to_char(lower(r), 'YYYY Mon') as "Month",
sum(upper(r) - lower(r)) as days
from (
select t.r * g.r as r
from
(
select daterange(start_date, end_date, '[]') as r
from t
) t
inner join
g on t.r && g.r
) s
group by 1
) s
order by to_timestamp("Month", 'YYYY Mon')
;
Month | days
----------+------
2014 Feb | 27
2014 Mar | 31
2014 Apr | 30
2014 May | 10
2014 Jun | 28
2014 Jul | 5