SQL 查询以获取多层次项
SQL query to get multihierarchy items
在我的 SQL Table 我有以下数据
ID Level Description Code MasterID
1 1 Cars AD0 NULL
2 1 Trucks JF1 NULL
3 1 Items YU2 NULL
4 2 New Cars AS3 1
5 2 Used Cars TG4 1
6 2 Car parts UJ5 1
7 2 New trucks OL6 2
8 2 Used trucks PL7 2
9 2 Truck parts KJL8 2
10 2 Factory stuff UY9 3
11 2 Custom stuff RT10 3
12 3 Toyota 6YH11 4
13 3 BMW 9OKH12 4
14 3 VW 13 5
15 3 Tiers Type I J14 6
16 3 Tiers Type II J15 6
17 3 Tiers Type III ADS16 9
18 3 Seats SA17 6
19 3 Doors UU18 6
20 3 Lights 9OL19 6
21 4 Left light GH20 20
22 4 Right light H21 20
23 4 Left door JHJ22 19
24 4 Michelin UY23 16
25 4 Vredestein GTF24 17
26 4 Dunlop 25 15
我的成就是获取每个项目的所有层次结构数据。例如,输出应该如下所示
ID Level Description Code MasterId1 Description1 MasterId2 Description2 MasterId3 Description3
24 4 Michelin UY23 16 Tiers Type II 6 Car Parts 1 Cars
.
.
19 3 Doors UU18 6 Car Parts 1 Cars NULL NULL
.
.
10 2 Factory Stuff UY9 3 Items NULL NULL NULL NULL
.
.
3 1 Items NULL NULL NULL NULL NULL NULL NULL
.
.
如果有人可以提供帮助或建议如何实现这一点?
这不是动态的,但可以很容易地实现。
使用递归 cte,您可以获得整个 table 的层次结构,并自我连接几次以获得所需的 table 结构。
;WITH cte AS
(
SELECT *, ID AS [RootID], 1 AS [MasterLevel] FROM Table1
UNION ALL
SELECT t1.*, cte.[RootID], cte.[MasterLevel] + 1 FROM Table1 t1
JOIN cte ON t1.ID = cte.MasterID
)
SELECT r.ID, r.[Level], r.[Description], r.[Code],
m1.ID AS MasterId1, m1.[Description] AS Description1,
m2.ID AS MasterId2, m1.[Description] AS Description2,
m3.ID AS MasterId3, m1.[Description] AS Description3
FROM cte r
LEFT JOIN cte m1 ON m1.[RootID] = r.[RootID] AND m1.MasterLevel = 2
LEFT JOIN cte m2 ON m2.[RootID] = r.[RootID] AND m2.MasterLevel = 3
LEFT JOIN cte m3 ON m3.[RootID] = r.[RootID] AND m3.MasterLevel = 4
WHERE r.MasterLevel = 1
ORDER BY r.RootID DESC, r.MasterLevel
这将构建一个动态 sql 以根据最大 Level
值获取主字段和描述字段。或者您可以通过更改 @MaxLevel
来定义要查看的级别
DECLARE @Sql VARCHAR(MAX) = '',
@SelectSql VARCHAR(MAX) = '',
@JoinSql VARCHAR(MAX) = '',
@MaxLevel INT,
@idx INT = 1
SET @MaxLevel = (SELECT MAX([Level]) FROM Table1)
WHILE @idx < @MaxLevel
BEGIN
SET @SelectSql = @SelectSql + REPLACE(', m<index>.ID AS MasterId<index>, m<index>.[Description] AS Description<index> ', '<index>', @idx)
SET @JoinSql = @JoinSql + REPLACE(' LEFT JOIN cte m<index> ON m<index>.[RootID] = r.[RootID] AND m<index>.MasterLevel = <index> ', '<index>', @idx)
SET @idx = @idx + 1
END
SET @Sql = '
;WITH cte AS
(
SELECT *, ID AS [RootID], 0 AS [MasterLevel] FROM Table1
UNION ALL
SELECT t1.*, cte.[RootID], cte.[MasterLevel] + 1 FROM Table1 t1
JOIN cte ON t1.ID = cte.MasterID
)
SELECT r.ID, r.[Level], r.[Description], r.[Code]' + @SelectSql
+ 'FROM cte r ' + @JoinSql
+ 'WHERE r.MasterLevel = 0
ORDER BY r.RootID DESC, r.MasterLevel'
EXEC(@Sql)
在我的 SQL Table 我有以下数据
ID Level Description Code MasterID
1 1 Cars AD0 NULL
2 1 Trucks JF1 NULL
3 1 Items YU2 NULL
4 2 New Cars AS3 1
5 2 Used Cars TG4 1
6 2 Car parts UJ5 1
7 2 New trucks OL6 2
8 2 Used trucks PL7 2
9 2 Truck parts KJL8 2
10 2 Factory stuff UY9 3
11 2 Custom stuff RT10 3
12 3 Toyota 6YH11 4
13 3 BMW 9OKH12 4
14 3 VW 13 5
15 3 Tiers Type I J14 6
16 3 Tiers Type II J15 6
17 3 Tiers Type III ADS16 9
18 3 Seats SA17 6
19 3 Doors UU18 6
20 3 Lights 9OL19 6
21 4 Left light GH20 20
22 4 Right light H21 20
23 4 Left door JHJ22 19
24 4 Michelin UY23 16
25 4 Vredestein GTF24 17
26 4 Dunlop 25 15
我的成就是获取每个项目的所有层次结构数据。例如,输出应该如下所示
ID Level Description Code MasterId1 Description1 MasterId2 Description2 MasterId3 Description3
24 4 Michelin UY23 16 Tiers Type II 6 Car Parts 1 Cars
.
.
19 3 Doors UU18 6 Car Parts 1 Cars NULL NULL
.
.
10 2 Factory Stuff UY9 3 Items NULL NULL NULL NULL
.
.
3 1 Items NULL NULL NULL NULL NULL NULL NULL
.
.
如果有人可以提供帮助或建议如何实现这一点?
这不是动态的,但可以很容易地实现。
使用递归 cte,您可以获得整个 table 的层次结构,并自我连接几次以获得所需的 table 结构。
;WITH cte AS
(
SELECT *, ID AS [RootID], 1 AS [MasterLevel] FROM Table1
UNION ALL
SELECT t1.*, cte.[RootID], cte.[MasterLevel] + 1 FROM Table1 t1
JOIN cte ON t1.ID = cte.MasterID
)
SELECT r.ID, r.[Level], r.[Description], r.[Code],
m1.ID AS MasterId1, m1.[Description] AS Description1,
m2.ID AS MasterId2, m1.[Description] AS Description2,
m3.ID AS MasterId3, m1.[Description] AS Description3
FROM cte r
LEFT JOIN cte m1 ON m1.[RootID] = r.[RootID] AND m1.MasterLevel = 2
LEFT JOIN cte m2 ON m2.[RootID] = r.[RootID] AND m2.MasterLevel = 3
LEFT JOIN cte m3 ON m3.[RootID] = r.[RootID] AND m3.MasterLevel = 4
WHERE r.MasterLevel = 1
ORDER BY r.RootID DESC, r.MasterLevel
这将构建一个动态 sql 以根据最大 Level
值获取主字段和描述字段。或者您可以通过更改 @MaxLevel
DECLARE @Sql VARCHAR(MAX) = '',
@SelectSql VARCHAR(MAX) = '',
@JoinSql VARCHAR(MAX) = '',
@MaxLevel INT,
@idx INT = 1
SET @MaxLevel = (SELECT MAX([Level]) FROM Table1)
WHILE @idx < @MaxLevel
BEGIN
SET @SelectSql = @SelectSql + REPLACE(', m<index>.ID AS MasterId<index>, m<index>.[Description] AS Description<index> ', '<index>', @idx)
SET @JoinSql = @JoinSql + REPLACE(' LEFT JOIN cte m<index> ON m<index>.[RootID] = r.[RootID] AND m<index>.MasterLevel = <index> ', '<index>', @idx)
SET @idx = @idx + 1
END
SET @Sql = '
;WITH cte AS
(
SELECT *, ID AS [RootID], 0 AS [MasterLevel] FROM Table1
UNION ALL
SELECT t1.*, cte.[RootID], cte.[MasterLevel] + 1 FROM Table1 t1
JOIN cte ON t1.ID = cte.MasterID
)
SELECT r.ID, r.[Level], r.[Description], r.[Code]' + @SelectSql
+ 'FROM cte r ' + @JoinSql
+ 'WHERE r.MasterLevel = 0
ORDER BY r.RootID DESC, r.MasterLevel'
EXEC(@Sql)