簡體   English   中英

Postgres SQL查詢,它將對嵌套JSON對象中的字段進行分組

[英]Postgres SQL query, that will group fields in nested JSON objects

我需要Postgres中的SQL查詢,該查詢生成帶有分組/繼承數據的JSON,請參見下面的示例。

有一個帶有以下示例數據的表“問題”:

+--------------------------------------+-------+------------+-----------------------+
|              product_id              | level |  typology  |        comment        |
+--------------------------------------+-------+------------+-----------------------+
| e1227f18-0c1f-4ebb-8cbf-a09c74ba14f5 |     1 | electronic | LED broken            |
| e1227f18-0c1f-4ebb-8cbf-a09c74ba14f5 |     1 | mechanical | missing gear          |
| e1227f18-0c1f-4ebb-8cbf-a09c74ba14f5 |     1 | mechanical | cover damaged         |
| e1227f18-0c1f-4ebb-8cbf-a09c74ba14f5 |     2 | electric   | switch wrong color    |
| e1227f18-0c1f-4ebb-8cbf-a09c74ba14f5 |     2 | mechanical | missing o-ring        |
| e1227f18-0c1f-4ebb-8cbf-a09c74ba14f5 |     2 | electric   | plug wrong type       |
| 3567ae01-c7b3-4cd7-9e4f-85730aab89ee |     1 | mechanical | gear wrong dimensions |
+--------------------------------------+-------+------------+-----------------------+

product_id, typology and comment are string.
level is an integer.

我想獲取此JSON:

{
  "e1227f18-0c1f-4ebb-8cbf-a09c74ba14f5": {
    "1": {
      "electronic": [ "LED broken" ],
      "mechanical": [ "missing gear", "cover damaged"]
    },
    "2": {
      "electronic": [ "switch wrong color", "plug wrong type" ],
      "mechanical": [ "missing o-ring" ]
    }
  },
  "3567ae01-c7b3-4cd7-9e4f-85730aab89ee": {
    "1": {
      "mechanical": [ "gear wrong dimensions"]
    }
  }
}

所以我開始寫這樣的查詢:

  SELECT array_to_json(array_agg(json_build_object(
    product_id, json_build_object(
      level, json_build_object(
        typology, comment
      )
    )
  ))) FROM issues

但我沒有意識到如何分組/聚合以獲得所需的JSON

分步演示:db <> fiddle

SELECT 
    jsonb_object_agg(key, value)
FROM (
    SELECT
        jsonb_build_object(product_id, jsonb_object_agg(key, value)) as products
    FROM (
        SELECT
            product_id,
            jsonb_build_object(level, jsonb_object_agg(key, value)) AS level
        FROM (
            SELECT
                product_id,
                level,
                jsonb_build_object(typology, jsonb_agg(comment)) AS typology
            FROM
                issues
            GROUP BY product_id, level, typology
        ) s, 
        jsonb_each(typology)
    GROUP BY product_id, level
    ) s,
    jsonb_each(level)
    GROUP BY product_id
) s,
jsonb_each(products)
  1. jsonb_agg()將一些值聚合到一個JSON數組中。 comments已完成。
  2. 之后,還有一個更復雜的步驟。 要將兩個不同的JSON對象聚合到一個對象中,您需要執行以下操作:

簡化的演示:db <> fiddle

首先,您需要使用jsonb_each()將元素擴展為keyvalue列。 現在,您可以使用聚合函數jsonb_object_agg()來聚合這兩列。 也可以看看

這就是為什么以下步驟看起來有些困難的原因。 聚合的每個級別( levelproduct_id )都需要這些步驟,因為您要將元素合並到單個非數組JSON對象中。

因為每個聚合都需要單獨的GROUP BY子句,所以每個步驟都在其自己的子查詢中完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM