Teradata 如何使用递归构建 JSON 层次结构
Teradata how to use recursion to build JSON hierarchy
什么是等效的 Teradata 语法来回答关于在 处找到的常见 table 表达式内部反向聚合的相同问题?
我正在尝试破解 Teradata 语法版本以迭代父子关系 table 并构建 JSON 将子的父项放置在父子关系中一个 JSON 字段。
这是上面列出的超链接问题中给出的答案,我认为它是为 PostgreSQL 编写的。我非常感谢帮助将其翻译成 TD,因为我认为这个答案应该能让我完成我的预期任务。如果不是,请让我直截了当。
我不确定 row_to_json(c) 调用的是什么 JSON_AGG(c.children)?我认为双冒号 (NULL::JSON) 正在将 null 转换为 JSON 数据类型?无论如何,我尝试了一些变体都无济于事。请帮忙。
这是给出的 PostgreSQL 语法答案:
WITH RECURSIVE cte AS (
SELECT id, parent_id, name, NULL::JSON AS children
FROM people p
WHERE NOT EXISTS ( -- only leaf nodes; see link below
SELECT 1 FROM people
WHERE parent_id = p.id
)
UNION ALL
SELECT p.id, p.parent_id, p.name, row_to_json(c) AS children
FROM cte c
JOIN people p ON p.id = c.parent_id
)
SELECT id, name, json_agg(children) AS children
FROM cte
GROUP BY 1, 2;
在将 PostgreSQL 转换为 Teradata 时,我遇到了一个限制,JSON 列不受 UNION 等集合操作的支持。
来回转换 JSON/VarChar 是一种解决方法:
CREATE VOLATILE TABLE people (id INT, name VARCHAR(20), parent_id INT) ON COMMIT PRESERVE ROWS;
INSERT INTO people VALUES(1, 'Adam', NULL);
INSERT INTO people VALUES(2, 'Abel', 1);
INSERT INTO people VALUES(3, 'Cain', 1);
INSERT INTO people VALUES(4, 'Enoch', 3);
WITH RECURSIVE cte AS (
SELECT id, parent_id, name,
CAST(NULL AS VARCHAR(2000)) AS children
FROM people p
WHERE NOT EXISTS (
SELECT * FROM people
WHERE parent_id = p.id
)
UNION ALL
SELECT p.id, p.parent_id, p.name,
-- VarChar -> JSON -> VarChar
CAST(JSON_COMPOSE(c.id,
c.name,
NEW JSON(c.children) AS children) AS VARCHAR(10000)) AS children
FROM cte c
JOIN people p ON p.id = c.parent_id
)
SELECT id, name,
JSON_AGG(NEW JSON(children) AS children) AS children
FROM cte
GROUP BY 1, 2;
结果类似,但不完全相同,Teradata 添加"children":
,例如:
{"children":{"id":4,"name":"Enoch","children":null}} -- Teradata
[{"id":4,"name":"Enoch","children":null}] -- PostgreSQL
最后添加 JSONExtract
以仅获取数组:
SELECT id, name,
JSON_AGG(NEW JSON(children) AS X).JSONExtract('$..X') AS children
FROM cte
GROUP BY 1, 2;
[{"id":4,"name":"Enoch","children":null}]
什么是等效的 Teradata 语法来回答关于在
我正在尝试破解 Teradata 语法版本以迭代父子关系 table 并构建 JSON 将子的父项放置在父子关系中一个 JSON 字段。
这是上面列出的超链接问题中给出的答案,我认为它是为 PostgreSQL 编写的。我非常感谢帮助将其翻译成 TD,因为我认为这个答案应该能让我完成我的预期任务。如果不是,请让我直截了当。
我不确定 row_to_json(c) 调用的是什么 JSON_AGG(c.children)?我认为双冒号 (NULL::JSON) 正在将 null 转换为 JSON 数据类型?无论如何,我尝试了一些变体都无济于事。请帮忙。
这是给出的 PostgreSQL 语法答案:
WITH RECURSIVE cte AS (
SELECT id, parent_id, name, NULL::JSON AS children
FROM people p
WHERE NOT EXISTS ( -- only leaf nodes; see link below
SELECT 1 FROM people
WHERE parent_id = p.id
)
UNION ALL
SELECT p.id, p.parent_id, p.name, row_to_json(c) AS children
FROM cte c
JOIN people p ON p.id = c.parent_id
)
SELECT id, name, json_agg(children) AS children
FROM cte
GROUP BY 1, 2;
在将 PostgreSQL 转换为 Teradata 时,我遇到了一个限制,JSON 列不受 UNION 等集合操作的支持。
来回转换 JSON/VarChar 是一种解决方法:
CREATE VOLATILE TABLE people (id INT, name VARCHAR(20), parent_id INT) ON COMMIT PRESERVE ROWS;
INSERT INTO people VALUES(1, 'Adam', NULL);
INSERT INTO people VALUES(2, 'Abel', 1);
INSERT INTO people VALUES(3, 'Cain', 1);
INSERT INTO people VALUES(4, 'Enoch', 3);
WITH RECURSIVE cte AS (
SELECT id, parent_id, name,
CAST(NULL AS VARCHAR(2000)) AS children
FROM people p
WHERE NOT EXISTS (
SELECT * FROM people
WHERE parent_id = p.id
)
UNION ALL
SELECT p.id, p.parent_id, p.name,
-- VarChar -> JSON -> VarChar
CAST(JSON_COMPOSE(c.id,
c.name,
NEW JSON(c.children) AS children) AS VARCHAR(10000)) AS children
FROM cte c
JOIN people p ON p.id = c.parent_id
)
SELECT id, name,
JSON_AGG(NEW JSON(children) AS children) AS children
FROM cte
GROUP BY 1, 2;
结果类似,但不完全相同,Teradata 添加"children":
,例如:
{"children":{"id":4,"name":"Enoch","children":null}} -- Teradata
[{"id":4,"name":"Enoch","children":null}] -- PostgreSQL
最后添加 JSONExtract
以仅获取数组:
SELECT id, name,
JSON_AGG(NEW JSON(children) AS X).JSONExtract('$..X') AS children
FROM cte
GROUP BY 1, 2;
[{"id":4,"name":"Enoch","children":null}]