Sql(CTE)クエリの正しい構造を作成しようとしていますが、できません。これは私が欲しいバージョンです 。
そしてこれは私の現在のバージョンです: 。ご覧のとおり、重複があり、それらを取り除く方法がわかりません。さらに、構造が間違っています。私はすでにここのような解決策を探そうとしましたが、解決策を思い付くことができませんでした。 CTEクエリは正しい構造を出力しませんか?
私の従業員テーブルは次のようになります http://sqlfiddle.com/#!6/428d2/2
正しい名前の列を作成するために使用するSQLクエリは次のとおりです。 http://sqlfiddle.com/#!6/bf4c1/4
私はMsSQL2012を使用しているので、最新の機能などを自由に使用してください。
CTEでルートノードを指定すると、問題なく機能します。
WITH Empl_Tab( Id ,
ParentId ,
LEVEL,
[Order]
) AS ( SELECT Employee.[EMPl Id] , Employee.[reports to the Boss] ,
0 AS LEVEL ,
CONVERT([varchar](MAX), Employee.[EMPl Id]) AS [Order]
FROM Employee
where [reports to the Boss] = 1
UNION ALL
SELECT Employee.[EMPl Id] ,
Employee.[reports to the Boss] ,
Empl_Tab.LEVEL+1 AS LEVEL ,
Empl_Tab.[Order] + CONVERT([varchar](30), Employee.[EMPl Id]) AS [Order]
FROM
Employee INNER JOIN Empl_Tab
ON Empl_Tab.Id = Employee.[reports to the Boss]
)
SELECT REPLICATE( '.' ,Empl_Tab.Id*1 )+Employee.Name AS Name
FROM
Employee INNER JOIN Empl_Tab
ON Empl_Tab.Id = Employee.[EMPl Id]
ORDER BY Empl_Tab.[Order]
SQLFiddle でコードを見ると、キーポイントだけが欠落しているため、正しい方向に進んでいます。
構文(BOLから) 再帰的CTEの==は:
WITH cte_name ( column_name [,...n] )
AS
(
CTE_query_definition –- Anchor member is defined.
UNION ALL
CTE_query_definition –- Recursive member is defined referencing cte_name.
)
-- Statement using the CTE
SELECT *
FROM cte_name
階層の最上位レベルである基本結果セットの作成が欠落しています。これは[reports to the Boss] = 1
で識別されます。したがって、誰にも報告しないCEOがいる可能性がある場合、彼はそれをNULLに設定します。
SELECT Employee.[EMPl Id] , Employee.[reports to the Boss] ,
0 AS LEVEL ,
CONVERT([varchar](MAX), Employee.[EMPl Id]) AS [Order]
FROM Employee
where [reports to the Boss] = 1
フィドルの残りのクエリは問題ないようです。
表示した結果を取得するには、以下が機能します。
;WITH Empl_Tab( Id ,
ParentId ,
LEVEL,
[Order]
) AS ( SELECT Employee.[EMPl Id] , Employee.[reports to the Boss] ,
0 AS LEVEL ,
CONVERT([varchar](MAX), Employee.[EMPl Id]) AS [Order]
FROM Employee
where [reports to the Boss] = 1
UNION ALL
SELECT Employee.[EMPl Id] ,
Employee.[reports to the Boss] ,
Empl_Tab.LEVEL+1 AS LEVEL ,
Empl_Tab.[Order] + CONVERT([varchar](30), Employee.[EMPl Id]) AS [Order]
FROM
Employee INNER JOIN Empl_Tab
ON Empl_Tab.Id = Employee.[reports to the Boss]
)
SELECT REPLICATE( ' ' ,Empl_Tab.Id*1 )+Employee.Name AS NAME,
Id as EMPID,
ParentId as SUPERVISORFK,
POSITION
FROM
Employee INNER JOIN Empl_Tab
ON Empl_Tab.Id = Employee.[EMPl Id]
ORDER BY Empl_Tab.[Order]
それが理解に役立つことを願っています。
また、@ Philがフィドルに持っているクエリを見てください。