web-dev-qa-db-ja.com

ツリーテーブルのSQLクエリ

ツリー構造のテーブルがあります。

id parentId name
----------------
1  0        Category1
2  0        Category2
3  1        Category3
4  2        Category4
5  1        Category5
6  2        Category6
7  3        Category7

SQLクエリの結果では、次のようなテーブルが必要です。

id parentId level name
----------------------
1  0        0     Category1
3  1        1     Category3
7  3        2     Category7
5  1        1     Category5
2  0        0     Category2
4  2        1     Category4
6  2        1     Category6

Ms-sqlクエリの作成を誰が手伝ってくれますか?ありがとう!

14
ihorko

A_horse_with_no_nameの回答を拡張して、SQL Serverの 再帰CTEの実装再帰単一レコードクロスアプライ)の使用方法を示します。 row_number()と組み合わせて、問題の正確な出力を生成します。

declare @t table(id int,parentId int,name varchar(20))
insert @t select 1,  0        ,'Category1'
insert @t select 2,  0,        'Category2'
insert @t select 3,  1,        'Category3'
insert @t select 4 , 2,        'Category4'
insert @t select 5 , 1,        'Category5'
insert @t select 6 , 2,        'Category6'
insert @t select 7 , 3,        'Category7'
;

WITH tree (id, parentid, level, name, rn) as 
(
   SELECT id, parentid, 0 as level, name,
       convert(varchar(max),right(row_number() over (order by id),10)) rn
   FROM @t
   WHERE parentid = 0

   UNION ALL

   SELECT c2.id, c2.parentid, tree.level + 1, c2.name,
       rn + '/' + convert(varchar(max),right(row_number() over (order by tree.id),10))
   FROM @t c2 
     INNER JOIN tree ON tree.id = c2.parentid
)
SELECT *
FROM tree
order by RN

正直なところ、IDで直接注文しているので、ID自体を使用してツリーの「パス」を生成することは機能しますが、row_number()関数を挿入すると思いました。

23
RichardTheKiwi
WITH tree (id, parentid, level, name) as 
(
   SELECT id, parentid, 0 as level, name
   FROM your_table
   WHERE parentid = 0

   UNION ALL

   SELECT c2.id, c2.parentid, tree.level + 1, c2.name
   FROM your_table c2 
     INNER JOIN tree ON tree.id = c2.parentid
)
SELECT *
FROM tree;

現在、テストするSQL Serverが手元にないため、タイプミス(構文エラー)が発生している可能性があります。

24