在这种情况下不理解 json_agg

2023-12-09

参考:查询包含 JSON 对象数组的 jsonb 列

begin;
CREATE TEMP TABLE segments (segments_id serial PRIMARY KEY, payload jsonb);
INSERT INTO segments (payload)
VALUES ('[{"kind": "person", "limit": "1"}, {"kind": "B", "filter_term": "fin"}]');
INSERT INTO segments (payload)
VALUES ('[{"kind": "person", "limit": "3"}, {"kind": "A", "filter_term": "abc"}]');
INSERT INTO segments (payload)
VALUES ('[{"kind": "person", "limit": "2"}, {"kind": "C", "filter_term": "def"}]');
commit;

CTE查询:

 with a  as (select jsonb_array_elements(s.payload) j from segments s)
    SELECT  json_agg(a.j) AS filtered_payload from a
    where j @> '{"kind":"person"}';

返回: [{"kind": "person", "limit": "1"}, {"kind": "person", "limit": "3"}, {"kind": "person", "limit": "2"}]

此查询A:

SELECT a.filtered_payload,
         a.ct_elem_row
        , sum(ct_elem_row) OVER () AS ct_elem_total
     , count(*)         OVER () AS ct_rows
FROM   segments s
           JOIN   LATERAL (
    SELECT json_agg(j.elem) AS filtered_payload, count(*) AS ct_elem_row
    FROM   jsonb_array_elements(s.payload) j(elem)
    WHERE  j.elem @> '{"kind":"person"}'
        ) a ON ct_elem_row > 0
WHERE  s.payload @> '[{"kind":"person"}]';

return : queryA

  1. 在QueryA中,结构如下:select ... from segments s join lateral filtered_payload.... segments是 3 行横向连接与一行 (filtered_pa​​yload)。filtered_payload根据 CTE 查询仅返回行,作为合并 JSON 数组。所以总的来说我很困惑json_agg在查询A中。

2021-10-05 16:36 +5:30 编辑: 即使下面的代码,a.filtered_payload返回 3 个 jsonb 数组,而不是 1 个 arrgregate json 数组。我不知道什么时候已经聚合的 jsonb 数组(使用 json_agg 函数)取消嵌套到多个 jsonb 数组。

 SELECT a.filtered_payload, s.*
FROM   segments s
           cross  JOIN   LATERAL (
    SELECT json_agg(j.elem) AS filtered_payload
    FROM   jsonb_array_elements(s.payload) j(elem)
    WHERE  j.elem @> '{"kind":"person"}') a;

我相信LATERAL JOIN在那里做事。 在您的原始查询中,您正在使用json_agg针对整个表数据集(通过过滤'{"kind":"person"}')

with a  as 
    (
        select jsonb_array_elements(s.payload) j 
        from segments s
    )
SELECT  json_agg(a.j) AS filtered_payload 
from a
where j @> '{"kind":"person"}';

同时,在第二个实例中,您一次使用一行进行操作LATERAL。这就是为什么你最终会得到 3 行单行"kind":"person"值而不是具有 3 个值的唯一行。

不确定您想要实现什么目标,但以下内容可能会让您朝着正确的方向前进

SELECT a.filtered_payload,
    a.ct_elem_row, 
    sum(ct_elem_row) OVER () AS ct_elem_total, 
    count(*)         OVER () AS ct_rows
FROM segments s
 JOIN LATERAL (
    SELECT json_agg(j.elem) AS filtered_payload, 
        count(*) AS ct_elem_row
    FROM   segments d, lateral jsonb_array_elements(d.payload) j(elem)
    WHERE  j.elem @> '{"kind":"person"}'
    ) a ON ct_elem_row > 0
WHERE  s.payload @> '[{"kind":"person"}]';

Results

                                            filtered_payload                                            | ct_elem_row | ct_elem_total | ct_rows
--------------------------------------------------------------------------------------------------------+-------------+---------------+---------
 [{"kind": "person", "limit": "1"}, {"kind": "person", "limit": "3"}, {"kind": "person", "limit": "2"}] |           3 |             9 |       3
 [{"kind": "person", "limit": "1"}, {"kind": "person", "limit": "3"}, {"kind": "person", "limit": "2"}] |           3 |             9 |       3
 [{"kind": "person", "limit": "1"}, {"kind": "person", "limit": "3"}, {"kind": "person", "limit": "2"}] |           3 |             9 |       3
(3 rows)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在这种情况下不理解 json_agg 的相关文章

随机推荐