Mic*_*een 5 sql-server t-sql json
我有一个看起来像这样的层次结构:
作为 TSQL 中的 JSON,它是这样的:
declare @Employees nvarchar(max) =
'{
"person": "Amy",
"staff": [
{ "person": "Bill" },
{
"person": "Chris",
"staff": [
{ "person": "Dan" },
{ "person": "Emma" }
]
}
]
}';
Run Code Online (Sandbox Code Playgroud)
这只是一个例子。实际数据可以是任何深度或广度不确定的树。
我发现的文档和所有示例都显示了自上而下的遍历。每个 JSON 路径都从根节点开始,并通过已知的节点名称导航到所需的节点。我没有发现从层次结构中的不确定深度开始并向上工作。我觉得我需要像传递闭包这样的东西。
给定一个名字,我想获得该名字的血统。例如,给定“Emma”,结果将是“Emma / Chris / Amy”。给定“比尔”,答案将是“比尔/艾米”。输出格式不重要;它可以是 JSON、字符串或结果集。名字是独一无二的。
这是对我自己的学习练习。只要它仍然是 JSONy,就可以将原始 JSON 表示更改为任何等效的内容。层次结构的邻接列表表示上的 JSON_QUERY 无法实现我的目标。
在我看来,这是一个非常普通的递归查询,只要您动态地解开 JSON。
如果HandyD会原谅一些轻微的抄袭......
declare @Employees nvarchar(max) =
'{
"person": "Amy",
"staff": [
{ "person": "Bill" },
{
"person": "Chris",
"staff": [
{ "person": "Dan" },
{ "person": "Emma" }
]
}
]
}';
;WITH hier ([Level], Parent, Person, staff) AS (
SELECT
1 AS [Level],
convert(nvarchar(255),'') AS Parent,
l1.person,
l1.staff
FROM OPENJSON(@Employees) WITH (
person NVARCHAR(255),
staff NVARCHAR(MAX) AS JSON
) l1
UNION ALL
select
[Level]+1,
convert(nvarchar(255),h.Person) as Parent,
oj.person,
oj.staff
from hier h
outer apply openjson(h.staff) with (
person NVARCHAR(255),
staff NVARCHAR(MAX) AS JSON
) oj
where [Level] < 100 -- or relevant maxrecursion level
and oj.Person is not null
)
SELECT
[Level],
Parent,
Person
FROM hier
order by [Level];
Run Code Online (Sandbox Code Playgroud)