如何对使用json聚合的子查询的结果进行排序?
如果我有这样的架构:
my-classes-1.0.1.jar
我通过子查询在json列上聚合plan_items结果。 像这样:
CREATE TABLE plans( id integer NOT NULL, name character varying(255));
CREATE TABLE plan_items ( id integer NOT NULL, plan_id integer NOT NULL, expected_at date, status integer);
JSON聚合按预期工作,并提供我需要的结果。好。 但我无法订购结果。
我试过了:
SELECT
plans.id,
plans.name,
jsonb_agg((SELECT pi_cols FROM
(SELECT plan_items.id, plan_items.expected_at, plan_items.status) pi_cols
)) AS plan_items_data
FROM
plans
INNER JOIN plan_items ON plan_items.plan_id = plans.id
GROUP BY
plans.id,
plans.name
ORDER BY plans.id;
还有:
jsonb_agg((SELECT pi_cols FROM
(SELECT plan_items.id, plan_items.expected_at, plan_items.status ORDER BY plan_items.expected_at) pi_cols
)) AS plan_items_data
但这些都没有解决。
有什么想法吗?
答案 0 :(得分:4)
根据Abelisto的建议,只需使用简单的aggregate expression with ordering:
jsonb_agg(plan_items ORDER BY plan_items.expected_at) AS plan_items_data
答案 1 :(得分:3)
使用所需的排序顺序连接表,并使用横向连接选择jsonb_agg()
的列:
select s.plan_id id, name, jsonb_agg(pi_col)
from (
select p.id plan_id, p.name, pi.id, expected_at, status
from plans p
join plan_items pi
on p.id = pi.plan_id
order by p.id, expected_at
) s,
lateral (
select plan_id id, expected_at, status
) pi_col
group by 1, 2
order by 1;
上述查询似乎比选择列表中具有子查询的查询更自然,更灵活(在大多数情况下更快)。但是为了获得更好的性能,您还应该使用Abelisto的建议:
select s.plan_id id, name, json_agg(pi_col order by pi_col.expected_at)
from (
select p.id plan_id, p.name, pi.id, expected_at, status
from plans p
join plan_items pi
on p.id = pi.plan_id
) s,
lateral (
select plan_id id, expected_at, status
) pi_col
group by 1, 2
order by 1;