从 SQL 到 SPL:summarize row counts by dynamic columns into json
数据库表 _temp_data 的每个列可以看作一个数组,数组成员有重复:
hobbies_1 |
hobbies_2 |
A |
E |
B |
F |
A |
A |
A |
F |
现在要对每一列分别进行分组计数,写成 json 格式:
hobbies_1 |
hobbies_2 |
{"A":3,"B":1} |
{"A":1,"E":1,"F":2} |
SQL:
With Grouped AS (
SELECT
td.hobbies_1,
td.hobbies_2,
COUNT(*) AS count
FROM _temp_data td
GROUP BY GROUPING SETS (
(td.hobbies_1),
(td.hobbies_2)
)
)
SELECT
jsonb_object_agg(g.hobbies_1, g.count) FILTER (WHERE g.hobbies_1 IS NOT NULL) AS hobbies_1,
jsonb_object_agg(g.hobbies_2, g.count) FILTER (WHERE g.hobbies_2 IS NOT NULL) AS hobbies_2
FROM Grouped g;
SQL先用 GROUPING SETS 对不同的列同时进行分组计数,再用 jsonb_object_agg 分别将每个记录集转为 json,代码比较繁琐;而且必须写出列名,灵活性较差;如果想支持动态列名,就要用存储过程,结构将变得复杂。SPL 不必写出列名:https://try.esproc.com/splx?3mF
A |
|
1 |
$select * from _temp_data.txt |
2 |
=E@bp(A1).(json(E@p(E@b(~.groups(~;count(~))))(1))) |
3 |
=A1.create().record(A2) |
A1:加载数据。
A2:将二维表 A1 转置为序列的序列,对每个小序列(对应每列)进行分组计数,再转换成 Json。函数 E 用于转换序列和序表,@p 表示二层序列转置,@b 表示去掉列名。记录集合转 Json 时比记录多了 [] 符号,这里用 (1) 取唯一的记录再转。
A3:按 A1 结构新建空二维表,填入 Json 序列 A2。
问题来源:https://stackoverflow.com/questions/78184303/how-to-transform-and-summarize-row-counts