[英]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.