SQL 多个自连接到列

SQL multiple self joins to columns

我在一个名为套件的 table 中有以下简化信息,不幸的是我无法控制

id  title            parentsuiteid
1   test             NULL
4   pay1             3
5   pay2             3
3   Bill Payments    2
14  Vouchers         2
15  Mini             2
2   Site Tests       NULL

我想要一个水平表示用于报告,例如

test
Site tests   Bill Payments  pay1
Site tests   Bill Payments  pay2
Site tests   Vouchers   
Site tests   Mini   

我正在测试连接

select a.id,a.title,b.title,a.parentsuiteid from #temp2 a
left outer join #temp2 b
on a.id = b.parentsuiteid

id  title           title       parentsuiteid
1   test            NULL            NULL
4   pay1            NULL            3
5   pay2            NULL            3
3   Bill Payments   pay1            2
3   Bill Payments   pay2            2
14  Vouchers        NULL            2
15  Mini            NULL            2
2   Site Tests      Bill Payments   NULL
2   Site Tests      Vouchers        NULL
2   Site Tests      Mini            NULL 

这适用于两个级别,但我无法预测未来会有多少级别,而且超过两个级别似乎变得复杂

如何让我的输出看起来像 +- 5 级的水平表示?

您可以使用递归 CTE:

WITH EmpsCTE
AS (
 SELECT empid
    ,mgrid
    ,firstname
    ,lastname
    ,0 AS distance
FROM HR.Employees
WHERE empid = 9

UNION ALL

SELECT M.empid
    ,M.mgrid
    ,M.firstname
    ,M.lastname
    ,S.distance + 1 AS distance
FROM EmpsCTE AS S
INNER JOIN HR.Employees AS M ON S.mgrid = M.empid
)
SELECT empid
,mgrid
,firstname
,lastname
,distance
FROM EmpsCTE;

empid       mgrid       firstname  lastname             distance 
----------- ----------- ---------- -------------------- ----------- 
9           5           Zoya       Dolgopyatova         0 
5           2           Sven       Buck                 1 
2           1           Don        Funk                 2 
1           NULL        Sara       Davis                3

试试这个:

SQL Fiddle

MS SQL Server 2008 架构设置:

CREATE TABLE temp
(
  ID int,
  title VARCHAR(50),
  parentsuiteid int null
)

INSERT INTO temp
VALUES
(1, 'test', NULL),
(4, 'pay1',3),
(5, 'pay2', 3),
(3, 'Bill Payments', 2),
(14, 'Vouchers', 2),
(15, 'Mini', 2),
(2, 'Site Tests', NULL)

查询 1:

;WITH recurs
AS
(
    SELECT ID, title, parentsuiteid, 0 as level
    FROM Temp
    WHERE parentsuiteid IS NULL
    UNION ALL
    SELECT t1.ID, CAST(t2.title + ' ' + t1.title as VARCHAR(50)), t1.parentsuiteid, t2.level + 1 
    FROM temp t1
    INNER JOIN recurs t2
        ON t1.parentsuiteid = t2.ID
)
SELECT title
FROM Recurs r1
WHERE NOT EXISTS (SELECT * from recurs r2 WHERE r2.parentsuiteid = r1.Id )

Results:

|                         TITLE |
|-------------------------------|
|                          test |
|           Site Tests Vouchers |
|               Site Tests Mini |
| Site Tests Bill Payments pay1 |
| Site Tests Bill Payments pay2 |