My goal is to prepare the necessary json for a d3.js tree diagram using sql server (2019). I'm using the sql below to allow up to six node levels. It builds a json string but the output requires editing because the d3.js diagram requires all the children nodes to be named "children".
declare @t table (nodeName varchar(50), name varchar(50), parentname varchar(50), type varchar(50), code varchar(50), label varchar(50), version varchar(50));
insert into @t(nodeName,name,parentname,type,code,label,version)
values
('NODE NAME 1','NODE NAME 1','','type3','N1','Node name 1','v1.0'),
('NODE NAME 2.1','NODE NAME 2.1','NODE NAME 1','type1','N2.1','Node name 2.1','v1.0'),
('NODE NAME 2.2','NODE NAME 2.2','NODE NAME 1','type1','N2.2','Node name 2.2','v1.0'),
('NODE NAME 2.3','NODE NAME 2.3','NODE NAME 1','type1','N2.3','Node name 2.3','v1.0'),
('NODE NAME 2.4','NODE NAME 2.4','NODE NAME 1','type1','N2.4','Node name 2.4','v1.0'),
('NODE NAME 2.5','NODE NAME 2.5','NODE NAME 1','type1','N2.5','Node name 2.5','v1.0'),
('NODE NAME 3.1','NODE NAME 3.1','NODE NAME 2.1','type2','N3.1','Node name 3.1','v1.0'),
('NODE NAME 3.2','NODE NAME 3.2','NODE NAME 2.1','type2','N3.2','Node name 3.2','v1.0'),
('NODE NAME 3.3','NODE NAME 3.3','NODE NAME 2.3','type1','N3.3','Node name 3.3','v1.0'),
('NODE NAME 3.4','NODE NAME 3.4','NODE NAME 2.3','type1','N3.4','Node name 3.4','v1.0'),
('NODE NAME 3.5','NODE NAME 3.5','NODE NAME 2.4','type2','N3.5','Node name 3.5','v1.0'),
('NODE NAME 3.6','NODE NAME 3.6','NODE NAME 2.5','type2','N3.6','Node name 3.6','v1.0'),
('NODE NAME 4.1','NODE NAME 4.1','NODE NAME 3.3','type4','N4.1','Node name 4.1','v1.0'),
('NODE NAME 4.2','NODE NAME 4.2','NODE NAME 3.4','type4','N4.2','Node name 4.2','v1.0'),
('NODE NAME 5.1','NODE NAME 5.1','NODE NAME 4.1','type4','N5.1','Node name 5.1','v1.0'),
('NODE NAME 5.2','NODE NAME 5.2','NODE NAME 4.1','type4','N5.2','Node name 5.2','v1.0'),
('NODE NAME 6.1','NODE NAME 6.1','NODE NAME 5.2','type4','N6.1','Node name 6.1','v1.0'),
('NODE NAME 6.2','NODE NAME 6.2','NODE NAME 5.2','type4','N6.2','Node name 6.2','v1.0');
with l1 as (select * from @t where nodename = 'NODE NAME 1')
,l2 as (select * from @t where parentname in (select nodename from l1))
,l3 as (select * from @t where parentname in (select nodename from l2))
,l4 as (select * from @t where parentname in (select nodename from l3))
,l5 as (select * from @t where parentname in (select nodename from l4))
,l6 as (select * from @t where parentname in (select nodename from l5))
select l1.*, l2.*, l3.*, l4.*, l5.*, l6.*
from l1
left join l2 on l2.parentname = l1.nodename
left join l3 on l3.parentname = l2.nodename
left join l4 on l4.parentname = l3.nodename
left join l5 on l5.parentname = l4.nodename
left join l6 on l6.parentname = l5.nodename
for json auto
Resulting json:
"nodeName": "NODE NAME 1",
"name": "NODE NAME 1",
"parentname": "",
"type": "type3",
"code": "N1",
"label": "Node name 1",
"version": "v1.0",
"l2": [
{
"nodeName": "NODE NAME 2.1",
"name": "NODE NAME 2.1",
"parentname": "NODE NAME 1",
"type": "type1",
"code": "N2.1",
"label": "Node name 2.1",
"version": "v1.0",
"l3": [
{
"nodeName": "NODE NAME 3.1",
"name": "NODE NAME 3.1",
"parentname": "NODE NAME 2.1",
"type": "type2",
"code": "N3.1",
"label": "Node name 3.1",
"version": "v1.0",
"l4": [
{
"l5": [
{
"l6": [
{}
]
}
]
}
]
},
Edited to work:
"nodeName": "NODE NAME 1",
"name": "NODE NAME 1",
"parentname": "",
"type": "type3",
"code": "N1",
"label": "Node name 1",
"version": "v1.0",
"children": [
{
"nodeName": "NODE NAME 2.1",
"name": "NODE NAME 2.1",
"parentname": "NODE NAME 1",
"type": "type1",
"code": "N2.1",
"label": "Node name 2.1",
"version": "v1.0",
"children": [
{
"nodeName": "NODE NAME 3.1",
"name": "NODE NAME 3.1",
"parentname": "NODE NAME 2.1",
"type": "type2",
"code": "N3.1",
"label": "Node name 3.1",
"version": "v1.0",
"children": []
},
I'm wondering if there is a way to write the query to avoid this editing.
1条答案
按热度按时间u59ebvdq1#
The only way to do this (without resorting to an iterative cursor-style solution) is to use a scalar User Defined Function which recurses down to get all levels of the JSON
db<>fiddle
Result