簡體   English   中英

BigQuery:如何聚合 STRUCT 或 JSON 字段中的記錄?

[英]BigQuery: How to aggregate records in a STRUCT or JSON field?

我想將一對列聚合為鍵值對的字典,以在多個記錄上構造一個 STRUCT 或 JSON STRING。

目前我的實現利用 JSON 和 STRING_AGG 的 STRING 性質來構建這樣一個 JSON 值:

SELECT
    id, 
    (
        "{" ||
        STRING_AGG(
            '"' || base.key || '":' || CAST(base.val AS STRING),
            ','
        ) || "}"
    )
    AS json_val
FROM (
    SELECT 1 AS id, "a" AS `key`, 100 AS val
    UNION ALL
    SELECT 1 AS id, "b" AS `key`, 200 AS val
    UNION ALL
    SELECT 1 AS id, "c" AS `key`, 300 AS val
    UNION ALL
    SELECT 2 AS id, "a" AS `key`, 400 AS val
    UNION ALL
    SELECT 2 AS id, "b" AS `key`, 500 AS val
    UNION ALL
    SELECT 2 AS id, "c" AS `key`, 600 AS val
    UNION ALL
    SELECT 3 AS id, "a" AS `key`, 700 AS val
) base
GROUP BY 1

結果如下:

id,json_val
1 ,{"a":100,"b":200,"c":300}    
2 ,{"a":400,"b":500,"c":600}    
3 ,{"a":700}

有沒有更具可讀性的方法? 某種 STRUCT_AGG(key_field STRING, value_field ) 或等效簽名的 JSON_DICT_AGG/JSON_STRUCT_AGG?

考慮以下方法

SELECT id, 
  REPLACE(TRANSLATE(FORMAT('%T', ARRAY_AGG(STRUCT(key, val))), '[]()', '{}'), '", ', '":') json_val
FROM (
    SELECT 1 AS id, "a" AS `key`, 100 AS val UNION ALL
    SELECT 1 AS id, "b" AS `key`, 200 AS val UNION ALL
    SELECT 1 AS id, "c" AS `key`, 300 AS val UNION ALL
    SELECT 2 AS id, "a" AS `key`, 400 AS val UNION ALL
    SELECT 2 AS id, "b" AS `key`, 500 AS val UNION ALL
    SELECT 2 AS id, "c" AS `key`, 600 AS val UNION ALL
    SELECT 3 AS id, "a" AS `key`, 700 AS val
) base
GROUP BY id       

與 output

在此處輸入圖像描述

如果你想把它包裝成 UDF - 請看下面的例子

CREATE TEMP FUNCTION ARRAY_TO_JSON(arr ANY TYPE) AS (
  REPLACE(TRANSLATE(FORMAT('%T', arr), '[]()', '{}'), '", ', '":')
);
SELECT id, 
  ARRAY_TO_JSON(ARRAY_AGG(STRUCT(key, val))) json_val
FROM (
. . .
) base
GROUP BY id       

順便說一句,你可以用你自己的版本做完全相同的“技巧”——如下例所示

CREATE TEMP FUNCTION ARRAY_TO_JSON(arr ANY TYPE) AS ((
  SELECT "{" || STRING_AGG('"' || key || '":' || val) || "}"
  FROM UNNEST(arr)
));
SELECT id, 
  ARRAY_TO_JSON(ARRAY_AGG(STRUCT(key, val))) json_val
FROM (
. . . 
) base
GROUP BY id     

所有相同的 output 已經出現在答案的頂部

暫無
暫無

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

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