0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

再帰CTE(WITH RECURSIVE)方式 vs. 多重LEFT OUTER JOIN方式

Posted at

現場で階層データ(ツリー構造)をSQLで扱う場合、再帰CTEWITH RECURSIVE)とLEFT OUTER JOIN(自己結合)の2つの代表的なアプローチがあります。本記事では、両者のクエリ例と結果イメージ、メリット・デメリットを整理します。

ルート (id=1)
├─ A (id=2)
    └─ 葉ノードA (id=4)
└─ B (id=3)

1. 再帰CTE(WITH RECURSIVE)方式

再帰CTEは、自己参照テーブル(例:**parent_id**カラムを持つカテゴリテーブル)の階層関係を可変な深さでたどり、ツリー構造を簡潔に取得できるのが特長です。

サンプルクエリ

WITH RECURSIVE node_tree AS (
  SELECT
    id,
    parent_id,
    name,
    sort_order,
    depth
  FROM
    category
  WHERE
    parent_id IS NULL

  UNION ALL

  SELECT
    c.id,
    c.parent_id,
    c.name,
    c.sort_order,
    c.depth
  FROM
    category c
    INNER JOIN node_tree nt ON c.parent_id = nt.id
)
SELECT
  id,
  parent_id,
  name,
  sort_order,
  depth
FROM
  node_tree
ORDER BY
  depth, sort_order;

期待される結果例

id parent_id name sort_order depth
1 NULL ルート 1 1
2 1 子A 1 2
3 1 子B 2 2
4 2 葉ノードA 1 3

2. 多重LEFT OUTER JOIN方式

階層の数が決まっている場合(たとえば「4段階まで」など)、LEFT OUTER JOINで自己結合を多重に重ねることで疑似的にツリー構造を1クエリで表現できます。

サンプルクエリ

SELECT
  c1.id   AS lv1_id, c1.name   AS lv1_name,
  c2.id   AS lv2_id, c2.name   AS lv2_name,
  c3.id   AS lv3_id, c3.name   AS lv3_name
FROM
  category c1
  LEFT OUTER JOIN category c2 ON c2.parent_id = c1.id
  LEFT OUTER JOIN category c3 ON c3.parent_id = c2.id
WHERE
  c1.parent_id IS NULL
ORDER BY
  c1.sort_order, c2.sort_order, c3.sort_order;

期待される結果例

lv1_id lv1_name lv2_id lv2_name lv3_id lv3_name
1 ルート 2 子A 4 葉ノードA
1 ルート 3 子B NULL NULL

両者の比較まとめ

項目 WITH RECURSIVE方式 LEFT OUTER JOIN方式
階層上限 無制限(深さに制限なし) 設定した分のみ(管理しやすいのは4~5段まで)
クエリの可読性 慣れないとやや複雑 階層深くなるとJOIN数で冗長に
柔軟性 階層の増減に強い 階層構造の変動に弱い
パフォーマンス 深い/大きなツリーは負荷大 JOIN数が増えるとパフォーマンス悪化
主な用途 組織図、カテゴリーツリー、無限階層メニューなど 段数が決まっているカテゴリ表示

まとめ

  • 再帰CTEは、階層の深さが未定・動的なケースや「全件検索」に有効で、構造の変化にも柔軟に追従できます。
  • *多重自己結合(LEFT OUTER JOIN)**は階層が限定的かつ一覧に横並びで出したいケースに有利ですが、拡張性は低いです。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?