填充数组交叉表中的缺失数据
filling missing data in array crosstab
如何将数据汇总到数组中,才不会遗漏数据
例如我要查询所有注册用户从一月到十二月的年度报告:
with s_table as (
SELECT
city,
gs.mounth as month,
coalesce(count(city),0) as count
FROM
generate_series('2017-01-01'::date, '2017-12-31'::date , interval '1 month') as gs(mounth)
LEFT JOIN "user"
ON to_char("user".datereg, 'YYYY-MM') = to_char(gs.mounth::date, 'YYYY-MM')
GROUP BY city, gs.mounth
)
select city,
array_agg(count) as count
from s_table
group by s_table.city
order by s_table.city;
它 returns 缺少数据:
|City |arr_agg|
|Dublin|{1}| //ONLY DECEMBER IS FILLED!
|Berlin|{1,4,5,10} //ONLY JAN,MAR,APR,OCT ARE FILLED!
期待结果
|City | Count users |
|Dublin|{0,0,0,0,0,0,0,0,0,0,0,1} |
|Berlin|{1,0,4,5,0,0,0,0,0,10,0,0}|
如何用'0'填充缺失的数据?
您需要为所有城市生成所有月份。要获取行,请考虑 cross join
:
with s_table as (
select c.city, gs.month as month,
count(u.city) as count
from generate_series('2017-01-01'::date, '2017-12-31'::date , interval '1 month') as gs(month) cross join
(select distinct u.city from user u) c left join
"user" u
on date_trunc('month', u.datereg,) = date_trunc(gs.month::date) and
u.city = c.city
group by c.city, gs.month
)
select city, array_agg(count order by month) as count
from s_table
group by s_table.city
order by s_table.city;
注意答案中的其他变化:
- 日期比较使用日期函数而不是字符串。
array_agg()
有一个 order by
。
- 无需将
generate_series()
的结果转换为日期。
count()
没有 return NULL
,所以 coalese()
是不必要的。
如何将数据汇总到数组中,才不会遗漏数据 例如我要查询所有注册用户从一月到十二月的年度报告:
with s_table as (
SELECT
city,
gs.mounth as month,
coalesce(count(city),0) as count
FROM
generate_series('2017-01-01'::date, '2017-12-31'::date , interval '1 month') as gs(mounth)
LEFT JOIN "user"
ON to_char("user".datereg, 'YYYY-MM') = to_char(gs.mounth::date, 'YYYY-MM')
GROUP BY city, gs.mounth
)
select city,
array_agg(count) as count
from s_table
group by s_table.city
order by s_table.city;
它 returns 缺少数据:
|City |arr_agg|
|Dublin|{1}| //ONLY DECEMBER IS FILLED!
|Berlin|{1,4,5,10} //ONLY JAN,MAR,APR,OCT ARE FILLED!
期待结果
|City | Count users |
|Dublin|{0,0,0,0,0,0,0,0,0,0,0,1} |
|Berlin|{1,0,4,5,0,0,0,0,0,10,0,0}|
如何用'0'填充缺失的数据?
您需要为所有城市生成所有月份。要获取行,请考虑 cross join
:
with s_table as (
select c.city, gs.month as month,
count(u.city) as count
from generate_series('2017-01-01'::date, '2017-12-31'::date , interval '1 month') as gs(month) cross join
(select distinct u.city from user u) c left join
"user" u
on date_trunc('month', u.datereg,) = date_trunc(gs.month::date) and
u.city = c.city
group by c.city, gs.month
)
select city, array_agg(count order by month) as count
from s_table
group by s_table.city
order by s_table.city;
注意答案中的其他变化:
- 日期比较使用日期函数而不是字符串。
array_agg()
有一个order by
。- 无需将
generate_series()
的结果转换为日期。 count()
没有 returnNULL
,所以coalese()
是不必要的。