16bit!

エンジニアじゃなくなっちゃった人が何かを書くブログ

【SQL】【Oracle】親子テーブルを結合して抽出する際に、1行目だけに親の情報を表示させる方法

要するにブレーク処理みたいなことをSQL1本でやりたいって話です。

サンプルテーブル

親テーブル:item_category
PK:category_id

category_id category_name
1 食料品
2 衣料品
3 日用品
4 嗜好品

子テーブル:item
PK:category_id, item_id

category_id item_id item_name
1 1001 りんご
1 1102 鳥モモ肉
1 1405 鮭切り身
2 1001 Tシャツ
2 1010 靴下
2 2025 ジャージ
3 1006 洗剤
3 1099 歯ブラシ
3 3005 ガムテープ
4 0704 たばこ
欲しい結果
category_name item_name
食料品 りんご
鳥モモ肉
鮭切り身
衣料品 Tシャツ
靴下
ジャージ
日用品 洗剤
歯ブラシ
ガムテープ
嗜好品 たばこ

カテゴリが変わる(ブレークする)度に、そのカテゴリの1行目だけにカテゴリ情報を表示させます。
2行目以降のカテゴリ欄は空白にします。

SQL
select
  c.category_name,
  i.item_name
from
  item_category c,
  item i
where
     (case 
      when (i.category_id, i.item_id)
           in (select category_id, min(item_id)
                from item sub
                group by category_id)
      then i.category_id
      else -1
     end) = c.category_id(+)
order by
  i.category_id, i.item_id

上記のように、case式を使って1行目以外の外部結合のキーを存在しない値(ここでは-1)にすることによって、
1行目だけにカテゴリ情報を表示させることができます。

終わり。

2012/01/06追記

テーブルのカラムがPK指定されていないと上記のようには取得できないようです。


※Qiitaとはてなのアクセス比較実験のために両方に投稿しています。