如何在一行中创建SQL Server树?

5ktev3wc  于 2023-02-11  发布在  SQL Server
关注(0)|答案(2)|浏览(107)
create table Test 
(
    Id int identity, 
    Name varchar(50) not null, 
    SName varchar(50) null, 
    ParentId int null 
)

 insert into Test 
  values ('aaa', 'bbb', null), ('adf', '22b', null), ('aad', 'bbsd',2),('asdsaa', 'bf', 3),('sdfs','sdf',3),('iopio','uiopio',3)

select * from Test

我有一个包含parentid的表,我想得到类似的值

Name SName "aaa" "bbb" , "adf" {"aad":{"asdsaa":"bf"}}

从所选值
我一直想用递归查询得到它,但是...

WITH tree_view AS 
(
    SELECT 
        Id, ParentId, Name, SName 
    FROM 
        Test
    UNION ALL 
    SELECT 
        parent.Id, parent.ParentId, parent.Name, parent.SName 
    FROM 
        Test parent 
    JOIN 
        tree_view tv ON parent.ParentId = tv.Id 
)
SELECT DISTINCT * 
FROM tree_view

我想得到这个

如果父ID不为空,则在一次销售中,我希望在Sname字段中获得Name:SName

1szpjjfi

1szpjjfi1#

我认为您需要使用PIVOT:下面是您可以尝试的类似解决方案
样表创建:

CREATE TABLE [dbo].[TestTable](
[Id] [int] NULL,
[Name] [nvarchar](50) NULL,
[Description] [nvarchar](50) NULL)

插入样本值:

INSERT INTO TestTable VALUES (1,'Test1a','TestDesc1a')
INSERT INTO TestTable VALUES (2,'Test1b','TestDesc1b')
INSERT INTO TestTable VALUES (3,'Test2a','TestDesc2a')
INSERT INTO TestTable VALUES (4,'Test2b','TestDesc2b')

使用透视表查询以获取所需输出:

SELECT  'Name' AS [Column], [1], [2],[3],[4]
FROM
(SELECT Name, id from TestTable) AS ST
PIVOT
(Max(Name) FOR ID IN ([1], [2],[3],[4])) AS PT

UNION

SELECT  'Description' AS [Column], [1], [2],[3],[4]
FROM
(SELECT  id,[Description] from TestTable) AS ST
PIVOT
(Max([Description]) FOR ID IN ([1], [2],[3],[4])) AS PT
ORDER BY [Column] DESC

输出:

Column         1           2          3           4
Name           Test1a      Test1b     Test2a      Test2b
Description    TestDesc1a  TestDesc1b TestDesc2a  TestDesc2b

希望这有助于解决您的问题。

mspsb9vt

mspsb9vt2#

如果你确信任何父节点只指向一个叶子节点,那么只使用字符串操作就可以生成你想要的JSON:

with rel_hier(id, parentid, name, sname, js) as (
    select m.id, m.parentid, m.name, m.sname, 
        CAST(CASE WHEN m.parentid IS NULL THEN 
        CONCAT('"' , m.sname , '"') ELSE 
        CONCAT('{"' ,  m.name , '" : "' , m.sname , '"}')  END AS VARCHAR(2000)) 
        js
    from Test m
    where not exists(select 1 from Test t1 where t1.parentid = m.id) 
    
    union all
    
    select m.id, m.parentid, m.name, m.sname, 
        CAST(CASE WHEN m.parentid IS NULL THEN r.js ELSE CONCAT('{"' , m.name , 
          '" : ' , r.js , '}') END AS VARCHAR(2000)) js
    from rel_hier r 
    join Test m on m.id = r.parentid
)
SELECT name, js as sname FROM rel_hier r
WHERE parentid IS NULL
;

name    sname
aaa "bbb"
adf {"aad" : {"asdsaa" : "bf"}}

但你也应该更好地解释一些水平〉3的替代规则。

相关问题