通常,您会使用递归 CTE 中多行的数据构建 [path] 列。在这种情况下,您正在“展平”多行表格。如果您有超过 5 个级别,这不会自动扩展。您必须为每个级别添加一列。话虽如此,您可以像这样做您要问的事情:
SQL Fiddle
MS SQL Server 2017 架构设置:
CREATE TABLE mytable (
[path] VARCHAR(13) null,
[desc] VARCHAR(70) null,
[lvl] SMALLINT null
)
INSERT INTO mytable ([path],[desc],[lvl])
VALUES
('D','Chicago',1)
,('DADB','Los Angeles',2)
,('DADB761','Miami',3)
,('DADB761G93','Detroit',4)
,('DADB761G93276','San Francisco',5)
,('DADB761G93277','Seattle',5)
查询 1:
WITH destruct AS (
SELECT DISTINCT
CAST([path] as nvarchar(512)) as code1
, CAST('' as nvarchar(512)) as code2
, CAST('' as nvarchar(512)) as code3
, CAST('' as nvarchar(512)) as code4
, CAST('' as nvarchar(512)) as code5
, CAST([desc] as nvarchar(512)) as desc1
, CAST('' as nvarchar(512)) as desc2
, CAST('' as nvarchar(512)) as desc3
, CAST('' as nvarchar(512)) as desc4
, CAST('' as nvarchar(512)) as desc5
, mt.[path]
, mt.lvl
FROM mytable as mt
WHERE lvl = 1
UNION ALL
SELECT
CAST(d.code1 as nvarchar(512)) as code1
, CAST(CASE WHEN d.lvl + 1 = 2 THEN RIGHT(mt.[path], LEN(mt.[path])-LEN(d.[path])) ELSE d.code2 END as nvarchar(512)) as code2
, CAST(CASE WHEN d.lvl + 1 = 3 THEN RIGHT(mt.[path], LEN(mt.[path])-LEN(d.[path])) ELSE d.code3 END as nvarchar(512)) as code3
, CAST(CASE WHEN d.lvl + 1 = 4 THEN RIGHT(mt.[path], LEN(mt.[path])-LEN(d.[path])) ELSE d.code4 END as nvarchar(512)) as code4
, CAST(CASE WHEN d.lvl + 1 = 5 THEN RIGHT(mt.[path], LEN(mt.[path])-LEN(d.[path])) ELSE d.code5 END as nvarchar(512)) as code5
, CAST(d.desc1 as nvarchar(512)) as desc1
, CAST(CASE WHEN d.lvl + 1 = 2 THEN mt.[desc] ELSE d.desc2 END as nvarchar(512)) as desc2
, CAST(CASE WHEN d.lvl + 1 = 3 THEN mt.[desc] ELSE d.desc3 END as nvarchar(512)) as desc3
, CAST(CASE WHEN d.lvl + 1 = 4 THEN mt.[desc] ELSE d.desc4 END as nvarchar(512)) as desc4
, CAST(CASE WHEN d.lvl + 1 = 5 THEN mt.[desc] ELSE d.desc5 END as nvarchar(512)) as desc5
, mt.[path]
, mt.lvl
FROM destruct as d
INNER JOIN mytable as mt
ON mt.lvl = d.lvl + 1
AND mt.[path] like d.[path] + '%'
AND d.lvl < 20 --Safety for debugging. Remove in Production.
)
SELECT *
FROM destruct as d
WHERE d.lvl = 5
Results:
| code1 | code2 | code3 | code4 | code5 | desc1 | desc2 | desc3 | desc4 | desc5 | path | lvl |
|-------|-------|-------|-------|-------|---------|-------------|-------|---------|---------------|---------------|-----|
| D | ADB | 761 | G93 | 276 | Chicago | Los Angeles | Miami | Detroit | San Francisco | DADB761G93276 | 5 |
| D | ADB | 761 | G93 | 277 | Chicago | Los Angeles | Miami | Detroit | Seattle | DADB761G93277 | 5 |
注意:所有CAST 表达式都是为了确保根查询和子查询具有相同的数据类型。如果没有它们,SQL Fiddle 会抛出有关类型不匹配的错误。