我有一张这样的桌子:
date number system_id
1 33.1 1
2 24.2 1
3 14.1 1
4 15.5 1
5 1113 1
1 4513 2
2 53.4 2
3 24.8 2
4 13.12 2
5 3333 2
我需要以这种格式转换的:
[
[date 1, number in date 1 (of system_id 1), number in date 1 (of system_id 2), number in date 1 (of system_id 3), ...],
[date 2, number 2 (of system_id 1), number 2 (of system_id 2), number 2 (of system_id 3), ...],
[date 3, number 3 (of system_id 1), number 3 (of system_id 2), number 3 (of system_id 3), ...],
[date 4, number 4 (of system_id 1), number 4 (of system_id 2), number 4 (of system_id 3), ...],
[...]
]
使用此查询:
SELECT date,
STRING_AGG(number::character varying, ',' order by system_id asc) as n
FROM MyTable
GROUP BY date
到目前为止,假设所有systems_ids
的{{1}}数目都相同,那么效果很好。但是,事实并非如此。让我们向数据库添加一行:
dates
我的结果现在看起来像这样:
date number system_id
6 1234 2
这确实是个问题,因为我依靠数字的顺序来代表不同的systems_id。
[
[1, 33.1, 4513],
[2, 24.2, 53.4],
...
[6, 1234]
]
当没有要聚集的值时如何填充默认值?
我需要在结果中的第6行显示为["date", "system_id_1", "system_id_2"]
或[6, 0, 1234]
或任何被认为是好的做法。尽管始终遵守顺序[6, NaN, 1234]
是最重要的。
或者,可以跳过整行。为此,我可以致电
["date", "system_id_1", "system_id_2"]
并以某种方式排除SELECT
date,
STRING_AGG(number::character varying, ',' order by system_id asc) as n
COUNT(date) as dates_count
FROM
MyTable
GROUP BY date
不等于dates_count
的所有行。但是如何?
答案 0 :(得分:1)
您可以使用cross join
生成行。然后引入数据并进行汇总:
select d.date,
string_agg( coalesce(t.number::character varying, ''), ',' order by s.system_id asc) as numbers
from (select distinct system_id from mytable) s cross join
(select distinct date from mytable) d left join
mytable t
on t.system_id = s.system_id and t.date = s.date
group by d.date;
我还建议您为此目的使用数组而不是字符串。
编辑:
或者,跳过不完整的行:
with ds as (
select date,
string_agg(number::character varying, ',' order by system_id asc) as n,
count(*) as num_system_ids,
max(count(*)) over () as max_num_system_ids
from MyTable
group by date
)
select ds.date, ds.n
from ds
where ds.num_system_ids = ds.max_num_system_ids;