在PostgreSQL中每月对结果分组几个日期

时间:2018-09-26 09:10:42

标签: sql postgresql

我在Postgres服务器上有下表,该表不断更新新日期(最旧的日期是3年前),但是为了简单起见,我们只列出3条记录:

id      date1         date2        date3 
1245    01/04/2018    05/04/2018   03/05/2018   
1255    01/04/2018    01/06/2018   04/06/2018 
1231    03/05/2018    07/05/2018   07/06/2018
1234    01/04/2017    01/04/2017   01/06/2018

我想创建一个sql视图,该视图将为我提供每种日期类型的单位总数

month     date1 date2 date3    
Jun       0     1     3   
May       1     1     1 
Apr       2     1     0
Apr17     1     1     0

有没有简单的方法可以做到这一点?到目前为止,我的sql看起来像

CREATE OR REPLACE VIEW monthly_view 
AS
SELECT row_number() OVER (ORDER BY b.id) AS id,
       'month',
       count(*) as date1,
       count(*) as date2,
       count(*) as date3
FROM mytable b
GROUP BY month
ORDER BY month desc

但是显然不起作用

2 个答案:

答案 0 :(得分:2)

经过测试!

路飞杜德, 您想做一件坏事,但这就是解决方案;)

    --all months
    with allmonths as (
        select to_char(date1, 'TMmon') as mm from tmp_a
        union
        select to_char(date2, 'TMmon') as mm from tmp_a
        union
        select to_char(date3, 'TMmon') as mm from tmp_a
    ),
    --count_in_date1
    count_in_date1 as (
        select
            t1.mm,
            count(t2.date1) as count_in_date1
        from
            allmonths t1 left join tmp_a t2 
                on to_char(t2.date1, 'TMmon') = t1.mm
        group by 
            t1.mm
    ),
    --count_in_date2
    count_in_date2 as (
        select
            t1.mm,
            count(t2.date2) as count_in_date2
        from
            allmonths t1 left join tmp_a t2 
                on to_char(t2.date2, 'TMmon') = t1.mm
        group by 
            t1.mm
    ),
    --count_in_date3
    count_in_date3 as (
        select
            t1.mm,
            count(t2.date3) as count_in_date3
        from
            allmonths t1 left join tmp_a t2 
                on to_char(t2.date3, 'TMmon') = t1.mm
        group by 
            t1.mm
    )
    --join all count together
    select t1.mm, count_in_date1, count_in_date2, count_in_date3 
    from count_in_date1 t1, count_in_date2 t2, count_in_date3 t3
        where t1.mm=t2.mm and t1.mm=t3.mm

答案 1 :(得分:1)

从生成月份开始。然后,我认为相关子查询是进行计算的一种简单方法:

select v.mon,
       (select count(*)
        from mytable t
        where to_char(date1, 'mon') = v.mon
       ) as date1,
       (select count(*)
        from mytable t
        where to_char(date2, 'mon') = v.mon
       ) as date2,
       (select count(*)
        from mytable t
        where to_char(date3, 'mon') = v.mon
       ) as date3
from (values ('jun', 6), ('may', 5), ('apr', 4)
     ) v(mon, mm) 
order by mm desc;

编辑:

尽管以上内容相当合理,但以下内容可能会具有更好的性能:

select mon, sum( (which = 1)::int ) as date1, sum( (which = 2)::int ) as date2,
       sum( (which = 3)::int ) as date3
from t cross join lateral
     (values (1, to_char(date1, 'mon'), extract(month from date1)),
             (2, to_char(date2, 'mon'), extract(month from date2)),
             (3, to_char(date3, 'mon'), extract(month from date3))
     ) v(which, mon, mm)
group by mon, mm
order by mm desc;

Here是一个学期。