SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

Oracle 11g R1新機能のPivotとUnPivot

select文で縦横変換

ダウンロード SourceCode (2.6 KB)

新規列の列名の省略

 下記のように、新規列の列名を省略することもできます。SQLを試行錯誤する段階などで使い道があるかもしれません。

新規列の列名を省略
select *
  from Courses
 pivot (max('○') for course in('SQL入門',
                                'UNIX基礎',
                                'Java中級'))
order by name;
出力結果
name 'SQL入門' 'UNIX基礎' 'Java中級'
吉田 null null
工藤 null
赤井 null
渡辺 null null
鈴木 null null

Pivotと、Pivotの代用(集約関数とdecode関数)との比較

 Pivotと、Pivotの代用(集約関数とdecode関数)は、使い分けるのがいいと思います。理由は下記です。

  • 理由1:Pivotでは、暗黙のgroup byが実行され、暗黙のgroup byはイメージしにくい
  • 理由2:Pivotで、不要な列を暗黙のgroup byの対象外にするには、インラインビューが必要
  • 理由3:Pivotで計算式を使用するには、インラインビューが必要

 理由1は、前述しましたので、理由2と3の例として、月ごとのValの合計を表示するselect文を比較してみましょう。

seals
dayCol Val bikou
2010-01-10 10 bikou1
2010-01-25 20 bikou2
2010-02-07 60 bikou3
2010-02-12 100 null
2010-03-11 200 null
2010-03-22 600 bikou4
Pivotの代用(集約関数とdecode関数)
select
sum(decode(extract(month from dayCol),1,Val)) as sum1,
count(decode(extract(month from dayCol),1,Val)) as cnt1,
sum(decode(extract(month from dayCol),2,Val)) as sum2,
count(decode(extract(month from dayCol),2,Val)) as cnt2,
sum(decode(extract(month from dayCol),3,Val)) as sum3,
count(decode(extract(month from dayCol),3,Val)) as cnt3
  from seals;
出力結果
sum1 cnt1 sum2 cnt2 sum3 cnt3
30 2 160 2 800 2
Pivotを使用
select *
  from (select extract(month from dayCol) as month,Val
          from seals)
 Pivot (sum(Val) as sum,
        count(*) as cnt
        for month in(1,2,3));
出力結果
1_SUM 1_CNT 2_SUM 2_CNT 3_SUM 3_CNT
30 2 160 2 800 2

 extract(month from dayCol)といった計算式を使ってPivotを行うには、インラインビューが必要となります。下記のselect文のように、extract(month from dayCol)といった計算式を使ってPivotを行うと文法エラーになるからです。

文法エラー ORA-01738: INキーワードがありません。
select *
  from seals
 Pivot (sum(Val) as sum,
        count(*) as cnt
        for extract(month from dayCol) in(1,2,3));

 また、bikouという列が、暗黙のgroup byのグループ化のキーの1つになることを防ぐためにも、bikou列を除いたselect文を使ったインラインビューが必要となります。

次のページ
3. UnPivotで行列変換 (列⇒行)

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

山岸 賢治(ヤマギシ ケンジ)

趣味が競技プログラミングなWebエンジニアで、OracleSQLパズルの運営者。AtCoderの最高レーティングは1204(水色)。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4985 2010/04/14 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー