* 複雑なSQL2 [#dfe94008]
* 複雑なSQL2 再帰的なデータ構造[#dfe94008]

再帰的なデータ構造のテーブルに対し、自己結合を使ってデータを取得する。

** 前提 [#nd4782c8]
カテゴリは上位のカテゴリとサブカテゴリが存在する。例えば、カテゴリには国語、数学、社会、理科、英語があり、理科カテゴリのサブカテゴリとして物理、化学、地学、生物があるような。カテゴリは2段階までで、サブサブカテゴリは存在しないとする。

** categoryテーブル [#x08f7954]
以下のようなカラムを持つ。category_idとparent_category_idが等しい場合、それは上位のカテゴリである。
- category_id (int)(PK)
- category_name (text)
- parent_category_id (int)

** 取得したいデータ [#f8c62ff7]
以上の条件で、すべてのカテゴリIDとそのペアレントID、およびそれぞれのカテゴリ名を取得したい。

例:
,カテゴリID,カテゴリ名,ペアレントID,ペアレントカテゴリ名
,15,日本史,3,社会
,16,世界史,3,社会
,17,地理,3,社会
,20,物理,4,理科
,21,化学,4,理科
,22,地学,4,理科
,23,生物,4,理科

** SQL [#h29a57b2]
SQLは以下の通り。
 select 
 cate1.category_id as cate_id, cate1.category_name as cate_name, 
 cate1.parent_category_id as p_cate_id, cate2.category_name as p_cate_name 
 from 
   category cate1
   join category cate2 
    on cate1.parent_category_id = cate2.category_id 
  where
    cate1.category_id <> cate1.parent_category_id
  order by cate1.parent_category_id, cate1.category_id;

** DBIC [#z3d3eb29]
DBICのコードは以下の通り。
 $c_rs = $c_rs->search_literal(
     'cate1.category_id <> cate1.parent_category_id'
     , { 
         from => [
             {cate1 => 'category'},
             [   
                 {cate2 => 'category'},
                 {'cate1.parent_category_id' => 'cate2.category_id'}
             ],
         ],
         select => [
             'cate1.category_id',
             'cate1.category_name',
             'cate1.parent_category_id',
             'cate2.category_name',
         ],
         as => [qw/
             category_id
             category_name
             parent_category_id
             parent_category_name
         /],
         order_by => [qw/
             cate1.parent_category_id
             cate1.category_id
         /]
     }
 );

** ポイント [#yb8876b9]
- fromを使って結合するテーブルを指定する。その際、joinの条件も書く。
- category_id <> parent_category_idのような条件はsearch()では出来ないっぽいので、search_literal()を使う。

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS