在Reverse aggregation inside of common table expression找到的常见表格表达式内回答相同问题的相同问题是什么等效的Teradata语法?
我正在尝试破解Teradata语法版本以迭代父子关系表并构建JSON,该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;
答案 0 :(得分:1)
将PostgreSQL翻译为Teradata时遇到限制,UNION等集合操作不支持JSON列。
来回转换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}]