根据 JSONB 第一个值按查询对组进行排序
Sort Group by query based on JSONB first values
我正在使用 PostgreSQL 并且我有以下 SQL 查询
WITH A AS
(
SELECT *,
jsonb_array_elements(event_days) as event_days_arr
FROM event
)
SELECT event_id::int,
MAX(area_id)::int AS area_id,
array_agg(event_days_arr) as event_days
FROM A
WHERE
event_days_arr->>'start_datetime' >= '2020-12-22' AND
event_days_arr->>'end_datetime' < '2020-12-22T19:00:00'
GROUP BY event_id, event_alias
ORDER BY
(event_days_arr->0->>'start_datetime'),
(event_days_arr->0->>'end_datetime');
如您所见,我有一个名为“event_days”的数组,我想根据该数组第一个元素中的键对结果进行排序
出于某种原因,我遇到以下错误:
ERROR: column "a.event_days_arr" must appear in the GROUP BY clause or be used in an aggregate function
我尝试使用 event_days、event_days_arr,但我无法根据每行的 JSONB 数组的第一个元素对查询结果进行排序
任何人都可以帮我对这个查询的结果进行排序吗?
我想你想按 event_days
的第一个元素分组,而不是 event_days_arr
。
这还不行吗?
WITH A AS (
SELECT *, jsonb_array_elements(event_days) as event_days_arr
FROM event
)
SELECT event_id::int,
MAX(area_id::int) AS area_id,
ARRAY_AGG(event_days_arr) as event_days
FROM A
WHERE
event_days_arr ->> 'start_datetime' >= '2020-12-22' AND
event_days_arr ->> 'end_datetime' < '2020-12-22T19:00:00'
GROUP BY event_id, event_alias
ORDER BY
event_days -> 0 ->> 'start_datetime',
event_days -> 0 ->> 'end_datetime';
Postgres 应该能够识别 order by
列依赖于 event_id
。如果没有,那么您需要将列添加到 group by
子句:
GROUP BY event_id, event_alias, event_days -> 0 ->> 'start_datetime', event_days -> 0 ->> 'end_datetime'
将时间范围的WHERE条件移动到通用table表达式中,一旦在FROM子句中使用set返回函数(应该使用它的地方)就可以做到这一点:
外部聚合也应该使用 jsonb_agg()
而不是 array_agg()
来完成,因为 ->
运算符只为 JSON 数组定义,而不是为原生数组定义。
列别名只能在 ORDER BY 部分“按原样”使用。如果你想使用一个表达式,你需要第二个层次,例如使用派生的 table 或 CTE:
WITH A AS
(
SELECT *
FROM event
cross join jsonb_array_elements(event_days) as arr(event_day)
WHERE arr.event_day ->> 'start_datetime' >= '2020-12-22'
AND arr.event_day ->> 'end_datetime' < '2020-12-22T19:00:00'
)
SELECT *
FROM (
SELECT event_id::int,
MAX(area_id)::int AS area_id,
jsonb_agg(event_day) as event_days
FROM A
GROUP BY event_id, event_alias
) t
ORDER BY event_days -> 0 ->> 'start_datetime',
event_days -> 0 ->>'end_datetime'
我正在使用 PostgreSQL 并且我有以下 SQL 查询
WITH A AS
(
SELECT *,
jsonb_array_elements(event_days) as event_days_arr
FROM event
)
SELECT event_id::int,
MAX(area_id)::int AS area_id,
array_agg(event_days_arr) as event_days
FROM A
WHERE
event_days_arr->>'start_datetime' >= '2020-12-22' AND
event_days_arr->>'end_datetime' < '2020-12-22T19:00:00'
GROUP BY event_id, event_alias
ORDER BY
(event_days_arr->0->>'start_datetime'),
(event_days_arr->0->>'end_datetime');
如您所见,我有一个名为“event_days”的数组,我想根据该数组第一个元素中的键对结果进行排序
出于某种原因,我遇到以下错误:
ERROR: column "a.event_days_arr" must appear in the GROUP BY clause or be used in an aggregate function
我尝试使用 event_days、event_days_arr,但我无法根据每行的 JSONB 数组的第一个元素对查询结果进行排序
任何人都可以帮我对这个查询的结果进行排序吗?
我想你想按 event_days
的第一个元素分组,而不是 event_days_arr
。
这还不行吗?
WITH A AS (
SELECT *, jsonb_array_elements(event_days) as event_days_arr
FROM event
)
SELECT event_id::int,
MAX(area_id::int) AS area_id,
ARRAY_AGG(event_days_arr) as event_days
FROM A
WHERE
event_days_arr ->> 'start_datetime' >= '2020-12-22' AND
event_days_arr ->> 'end_datetime' < '2020-12-22T19:00:00'
GROUP BY event_id, event_alias
ORDER BY
event_days -> 0 ->> 'start_datetime',
event_days -> 0 ->> 'end_datetime';
Postgres 应该能够识别 order by
列依赖于 event_id
。如果没有,那么您需要将列添加到 group by
子句:
GROUP BY event_id, event_alias, event_days -> 0 ->> 'start_datetime', event_days -> 0 ->> 'end_datetime'
将时间范围的WHERE条件移动到通用table表达式中,一旦在FROM子句中使用set返回函数(应该使用它的地方)就可以做到这一点:
外部聚合也应该使用 jsonb_agg()
而不是 array_agg()
来完成,因为 ->
运算符只为 JSON 数组定义,而不是为原生数组定义。
列别名只能在 ORDER BY 部分“按原样”使用。如果你想使用一个表达式,你需要第二个层次,例如使用派生的 table 或 CTE:
WITH A AS
(
SELECT *
FROM event
cross join jsonb_array_elements(event_days) as arr(event_day)
WHERE arr.event_day ->> 'start_datetime' >= '2020-12-22'
AND arr.event_day ->> 'end_datetime' < '2020-12-22T19:00:00'
)
SELECT *
FROM (
SELECT event_id::int,
MAX(area_id)::int AS area_id,
jsonb_agg(event_day) as event_days
FROM A
GROUP BY event_id, event_alias
) t
ORDER BY event_days -> 0 ->> 'start_datetime',
event_days -> 0 ->>'end_datetime'