這是以前考古題發問的,因為最近被挖出來,以下我的SQL解法,參考看看
原始貼文:傳送門
3/3 新增線條符合版+註解說明 ![]()

drop table if exists #Tmp
create table #Tmp(
item nvarchar(50)
,part nvarchar(50)
)
insert into #Tmp
values('11401-3412-1', '90514-20299O')
,('11409-3320', '11409-3321-A')
,('11409-3320', '11409-3322')
,('11409-3416-1', 'L608M')
,('11413-2400-1', '11413-3400-1')
,('11413-2400-1', '11502-3502-A')
,('11413-3400-1', '11409-3416-1')
,('11413-3400-1', '11413-3410-1')
,('11413-3410-1', '11401-3412-1')
,('11413-3410-1', '11413-3411-1')
,('11413-3411-1', '90505-45238O')
,('11426-2300-A', '11409-3320')
,('11426-2300-A', '11409-3332-B')
,('11426-2300-A', '11409-3333-B')
,('11426-2300-A', '11426-2311-2')
,('11426-2300-A', '14402-3335-B')
,('11426-2300-A', '41101-3334')
,('11426-2311-2', '11426-3313')
,('11426-3207', '90512-16348E')
,('11433-2000-D', '11426-2950-A')
,('11433-2000-D', '11433-2100-C')
,('11433-2100-C', '11101-3503')
,('11433-2100-C', '11101-3504')
,('11433-2100-C', '11103-3702')
,('11433-2100-C', '11413-2400-1')
,('11433-2100-C', '11413-2501-A')
,('11433-2100-C', '11413-3400-1')
,('11433-2100-C', '11426-2300-A')
,('11433-2100-C', '11433-2200-A')
,('11433-2100-C', '11502-2520-A')
,('11433-2100-C', '11502-2531-A')
,('11433-2100-C', '11502-3611')
,('11433-2100-C', '11502-3613')
,('11433-2100-C', '11502-3615')
,('11433-2100-C', '12501-3621')
,('11433-2100-C', '12501-3901')
,('11433-2100-C', '12501-3902-A')
,('11433-2100-C', '14301-3701')
,('11433-2100-C', 'CF241249-G01')
,('11433-2200-A', '11401-3202-A')
,('11433-2200-A', '11426-3207')
,('11433-2200-A', '11433-2201')
,('11433-2200-A', '11433-2P')
,('11433-2201', '90504-29330E')
,('11433-2P', '11401-3203')
,('11433-2P', '11401-3204')
,('11433-2P', '11433-3209')
,('11433-2P', '11502-2205')
,('11502-2520-A', '11502-2521-1')
,('11502-2520-A', '11502-2522-1')
,('11502-2520-A', '11502-3523-A')
;WITH ChildInfo AS (
--先產生額外資訊,紀錄節點及順序
SELECT item,
part,
ROW_NUMBER() OVER (PARTITION BY item ORDER BY part) AS child_pos,
COUNT(*) OVER (PARTITION BY item) AS cnt
FROM #Tmp a
)
, Tree AS (
--首先第一層查詢
SELECT
--父節點
a.item,
--子節點
a.part,
--起始階層
1 AS lvl,
--將此子節點名稱,先轉為統一格式
CAST(a.part AS varchar(200)) AS display,
--上層節點紀錄
CAST('' AS varchar(200)) AS SubPrefix,
--同階層判斷,最後子節點紀錄【└】,不是最後子節點紀錄【├】
CAST((
case when b.child_pos <> b.cnt
then '├'
else '└'
end
) AS varchar(200)) AS prefix,
--目前節點序
Convert(int,b.child_pos) child_pos,
--總節點序
Convert(int,b.cnt) cnt,
--樹狀圖排序
CAST(Right('00' + CAST(b.child_pos AS varchar(10)),3) AS varchar(50)) AS path
FROM #Tmp a
inner join ChildInfo b on a.part = b.part
--起始節點的設定
WHERE a.item = '11433-2000-D'
--遞迴UNION標準作法
UNION ALL
--開始第二層後的遞迴查詢
SELECT
--父節點
ci.item,
--子節點
ci.part,
--目前階層
tr.lvl + 1,
--將此子節點名稱,先轉為統一格式
CAST(ci.part AS varchar(200)),
--上層節點紀錄
tr.prefix,
CAST(
--將上層節點紀錄轉換,【└】轉為【空白】代表下方節數結束,【├】轉為【│】代表下方節點還有
Replace(Replace(tr.prefix,'└',' '),'├','│') +
--同階層判斷,最後子節點紀錄【└】,不是最後子節點紀錄【├】
CASE
WHEN ci.child_pos <> ci.cnt
THEN '├'
ELSE '└'
END
AS varchar(200)),
--目前節點序
CAST(ci.child_pos as int),
--總節點序
ci.cnt,
--樹狀圖排序
CAST(tr.path + '.' + Right('00' + CAST(ci.child_pos AS varchar(10)),3) AS varchar(50))
FROM Tree tr
INNER JOIN ChildInfo ci ON tr.part = ci.item
)
--最後展出樹狀圖資料
SELECT
prefix
+ NCHAR(0x2775 + lvl)
+ display AS TreeLine
,SubPrefix
,prefix
,child_pos
,cnt
,path
FROM Tree
ORDER BY path;