我有一个带有模板和响应表的Postgrs数据库,每个模板定义了它有多少行和项目,响应将项目放在行中.我希望能够查询一个合并的响应与"平均"放置在所有响应为任何模板.

template_post

id data
1 {"items":[{"id":0},{"id":1},{"id":2},{"id":3}],"rows":[{"id":"0","title":"First row"},{"id":"1","title":"Second row"},{"id":"3","title":"Third row"},{"id":"4","title":"Fourth row"}]}
2 ...

response_post

id template_id [FK] data
1 1 {"filled_rows":[{"row_id":4,"item_ids":[0,1,3]}]}
2 1 {"filled_rows":[{"row_id":2,"item_ids":[2]}]}
3 1 {"filled_rows":[{"row_id":0,"item_ids":[1]},{"row_id":2,"item_ids":[2]},{"row_id":4,"item_ids":[3]}]}

在这种情况下,查询应该返回以下合并响应:

{
  "filled_rows": [
    {
      "row_id": 0,
      "item_ids": [1]
    },
    {
      "row_id": 2,
      "item_ids": [2]
    },
    {
      "row_id": 4,
      "item_ids": [0,3]
    }
  ]
}

在不明确的情况下,当一个项目在多个行中出现相同次数时,它应该放在这些行的第一行.

推荐答案

这里需要几个层次的聚合.

  • 首先,在相关子查询中,将filled_rowsitem_ids分解为单独的行.
  • 合计item_id,取最小row_id.
  • 聚合row_id,取一个item_ids的JSONarray.
  • 将整个内容聚合起来,以在一个JSON中获取所有行
SELECT
  tp.id,
  r.result
FROM template_post tp
CROSS JOIN LATERAL (
    SELECT
      jsonb_build_object(
        'filled_rows', jsonb_agg(byRow.*)
      ) AS result
    FROM (
        SELECT
          byItem.row_id,
          jsonb_agg(byItem.item_id) AS item_ids
        FROM (
            SELECT
              MIN((r.value ->> 'row_id') ::int) AS row_id,
              i.value::int AS item_id
            FROM response_post rp
            CROSS JOIN jsonb_array_elements(rp.data -> 'filled_rows') r
            CROSS JOIN jsonb_array_elements_text(r.value -> 'item_ids') i
            WHERE rp.template_id = tp.id
            GROUP BY
              i.value::int
        ) byItem
        GROUP BY
          byItem.row_id
    ) byRow
) r;

db<>fiddle

Sql相关问答推荐

基于时间的SQL聚合

如何用3个(半)固定位置建模团队,并有效地搜索相同/不同的团队?

如果开始期间不存在PostgresSql回填数据

如何在不更改S代码的情况下,判断存储过程调用了多少次clr函数?

收到%1、%2或%2邮箱的唯一客户

如何在SQL Server中拆分包含字符和数字的列?

按分隔符和总和分析字符串

在查询Oracle SQL中创建替代ID

SQL到Snowflake-转换嵌套的SELECT(值

SQL仅返回第一个字母在A-Z之间的值

如何解决错误;ORA-00911:无效字符;在果朗?

当 ansible 变量未定义或为空时,跳过 sql.j2 模板中的 DELETE FROM 查询

SQL Server - 判断 ids 层次 struct 中的整数 (id)

使用SQLAlchemy和Postgres数据库创建新行时,为什么我的创建日期比更新日期晚?

PostgreSQL中如何提取以特定字符开头的字符串中的所有单词?

标量子查询中的窗口函数不起作用

根据是否存在值组合分组并 Select 行

使用其他表 SUM 的交换价格转换价格并获得 AVG

如何将多行的查询结果合并为一行

使用一组值进行分组和计数