我在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
但是显然不起作用
答案 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是一个学期。