ログイン記事を投稿する会員登録はこちら!ヘルプ

相関サブクエリで行と行を比較する

[初級〜中級] 集合指向言語としてのSQL:その3
ミック [著]  | 
評価:4.27 σ = 1.27
公開:07/02/08
Web
DB
EZ新着
RZ新着
SQLで同一行内の列同士の比較をすることは簡単です。それに比べて、異なる行を比較対象に使うことは、そう簡単ではありません。しかしそれは、SQLでは行間比較を記述できないという意味ではありません。本稿では、相関サブクエリを利用した行間比較の応用例を紹介します。
サンプルコード 2.0KB (103)
Page 1 / 2 / 3 / 4

はじめに

 SQLでは、同じ行内の列同士を比較することは簡単にできます。普通にWHERE句に「col_1 = col_2」のように書けばよいだけですから。一方、異なる行の間で列同士を比較することは、それほど簡単ではありません。ですがそれは、SQLで行間比較ができないということではありません。手続き型言語とはかなり異なる発想に基づいていますが、SQLでもそうした処理を記述することが可能です。

 SQLで行間比較をする際に威力を発揮するのが相関サブクエリ、特に自己結合と組み合わせた「自己相関サブクエリ」です。本稿では、この技術を使った行間比較の応用方法を、具体例を通して解説します。

稼働環境

  • Oracle
  • SQL Server
  • DB2
  • PostgreSQL
  • MySQL(バージョン4.1以上)

対象読者

 相関サブクエリの基本的な使い方を知っている方。CASE式、自己結合、スカラ・サブクエリについての知識があると望ましいです。とりわけ、自己結合と親和性が高い技術なので、未読の方は『自己結合の使い方』を先に読むと理解が増すでしょう。

成長・後退・現状維持

 行間比較が必要になる代表的な業務要件として、経時的なデータを記録したテーブルを使って、時系列分析を行うケースがあります。例えば、ある会社の年商を記録する次のようなテーブルを考えます。

Sales
年度(year)年商(億円)(sale)
199050
199151
199252
199352
199450
199550
199649
199755
年商の推移
年商の推移

 このデータを使って、「前年に比べて年商が増えたのか、減ったのか、変わらなかったのか」をSQLで出力します。試しに「変わらなかった」パターンを求めてみます。この場合、テーブルから現状維持の年、つまり93年と95年を求めます。手続き型言語の考え方に従えば、

  1. 年度で昇順にソートする。
  2. ループさせて1行ずつ直前の行のsale列と比較する

 というやり方になります。しかしもちろん、SQLでこんな発想をしてはいけません。こういうときは、「Sales」テーブルとは別に、「前年の行」を保持する集合(S2)を、もう1つ追加しましょう。

前年と年商が同じ年度を求める その1:相関サブクエリの利用
SELECT year,sale
  FROM Sales S1
 WHERE sale = (SELECT sale
                 FROM Sales S2
                WHERE S2.year = S1.year - 1)
 ORDER BY year;
結果
year   sale
-----  -----
1993   52
1995   50

 サブクエリ内の「S2.year = S1.year - 1」という条件によって、比較対象の行を1行「ずらして」いるわけです。相関サブクエリと自己結合は同値変換可能な場合が多いので、自己結合で書けば次のようになります。

前年と年商が同じ年度を求める その2:自己結合の利用
SELECT S1.year, S1.sale
  FROM Sales S1, 
       Sales S2
 WHERE S2.sale = S1.sale
   AND S2.year = S1.year - 1
 ORDER BY year;

 どちらの方がパフォーマンスが良いかというのは、一概には言えません。環境によって左右されるので、比較してみてください。

 では次にこれを応用して、各年度について、前年に比べて成長したのか、後退したのか、それとも現状維持だったのかを一度に求めてみましょう。

前年との比較結果を全年度について一覧表示する

 
1 2 3 4
→
INDEX
相関サブクエリで行と行を比較する
Page 1
はじめに
対象読者
成長・後退・現状維持
前年との比較結果を一覧表示する
時系列に歯抜けがある場合:直近と比較
移動累計と移動平均
オーバーラップする期間を調べる
おわりに
参考資料
関連記事
db
db
評価を送信する


著者紹介
ミック (ミック)
主にOracleを使ったデータウェアハウス業務に従事するDBエンジニア。
HPのコンテンツ『リレーショナル・データベースの世界』。

著書:
達人に学ぶ SQL徹底指南書』(翔泳社、2008)

訳書:
ジョー・セルコ『SQLパズル 第2版』(翔泳社、2007)

講演資料:
「みんなまとめて面倒みよう」(デブサミ2008、2008/02/13)

『Web+DB Press』(Vol.44〜)で「SQLアタマアカデミー」を連載中。
コメント
(最新日付順:新着コメントRSS配信中!

名前:*
メールアドレス(名前にリンク):
URL(名前にリンク):
タイトル:
内容(テキストのみ1200文字まで、リンクタグ入力不可):*
アイコン:
なし

利用規約に同意して

トラックバック
この記事のトラックバックURL:
スパム対策で、トラックバックはデフォルトで非公開とし、編集部チェックを通した上で公開させて頂いております。重複した登録などにご注意ください。主な判断基準は、「当該記事へ有効なリンクが張られている」「内容に関連性がある」の2点を満たしていることです。
Trackback (0)
記事は編集作業を経て公開されていますが、あくまで情報提供を第一の目的としたものであり、 内容には、不正確な記述、執筆者の予断や誤解に基づくもの、リンク切れ、環境要件が古いものが含まれていることがあります。 記事(翻訳記事を除く)の訂正に関しては、編集部の判断により随時対応することがありますが、各著作権者および(株)翔泳社はその内容の完全性を一切保障しません。 「投稿」の性質上、各著作権者は読者より訂正の依頼があったとしても対応できないこともあります。 記事内容の運用により派生した損害を含むあらゆる結果について、各著作権者および(株)翔泳社は一切の責任を持ちません。 各著作権者は記事内容に関するあらゆるサポートに付いてもその義務を放棄しています。あくまで記事は投稿され、編集を経て、公開された時点で完結したものであり、公開以降もサポートするかどうかは各者の任意事項となります。あらかじめご了承ください。
最新ニュース ≫一覧
最新記事 ≫一覧
一般投稿
VB.NETで仮想CPUを作ろう (4) - テストドライバの改良
「jMaki on Rails」の導入方法とRevolverコンポーネントのカスタマイズ
VB.NETで仮想CPUを作ろう (3) - 仮想CPUのGUI化
VB.NETで仮想CPUを作ろう (2) - レジスタの実装
RoRのWebサービスと連携する、Adobe AIRアプリケーションの自動生成
最近のコメント
64Bit化していく過程で、 ますます、機械語などと縁遠くなる中で 今書いて...(semember40505:08/09)
 機械猫の「了解」は「ニャジャー」がいいなぁと、ふと思いました。まあ、それだけな...(sanadan:08/08)
ソフトウエア開発文化の基礎となる部分の 文書化に重きが置かれていないので、 ...(匿名キボウ:08/01)
編集部ブログ
夏季休業のお知らせ(8/11〜8/15)()
Googleストリートビューと顔認識のアレコレ()
新検索エンジンCuilの出現で改めて考える「検索エンジンの精度ってなんじゃらほい」()
サイトメンテナンスのお知らせ(2008/07/29 18:00〜20:00)()
キャリア構築・転職支援マガジン「CAREERzine」(キャリアジン) プレオープン!()
サイト統計
はてなブックマーク合計数 CodeZineのはてなブックマーク数
昨日までの登録メンバー数昨日までの総メンバー数