SQL緊急救命室

第2回 冗長性症候群~条件分岐をUNIONで表現するなかれ

この記事を読むのに必要な時間:およそ 8 分

ここはとある街の総合病院。

ここには通常の診療科のほかに,一風変わった診療科が存在する。

何軒もの病院をたらいまわしにされた,手の施しようのないSQLや,今すぐに改善が必要なSQLが担ぎ込まれる救命室である。

それがSQL緊急救命室,略してSER(SQL Emergency Room)⁠

そう,ここは国内でも唯一のプログラミング専門外来である。

ロバート
救命室部長。腕の立つエンジニアだが,口が悪く性格はもっと悪い四十オヤジ。

ヘレン
救命室副部長。若いながらもロバートに次ぐ実力を持つ才媛。救命室の良心。

ワイリー
インターンで救命室に配属された不運な学生。無給で治療から雑務全般にこき使われる。エンジニアとしては新人に毛が生えたレベル。

SQLにおける条件分岐

(AM10:00 休憩室。ワイリーが机に向かって一人で何かしている)

どってぃろーんどってぃろーん,ぽぽぽんぽーん,どってぃろーん…


(休憩室のドアを開けて)あら,鼻歌交じりで,ご機嫌ね。


ああ,どうも。うふふ,今日はロバート先生,用事で遅れるそうです。


なるほど,束の間の休息ね。それじゃ鼻歌の一つも飛び出すわけだわ。

そういうことです。どってぃろーん…


(変なメロディー…)ところでワイリー,あなた何やってるの?


え? ああ,これは大学の課題。今日が締め切りなんです。


UNIONで条件分岐するのは正しいか

ふうん,どれどれ…。

問1:商品を管理する図1のようなテーブルItemsが存在する。各商品について,税抜き価格(外税)⁠税込み価格(内税)の両方を保持している。2002年から,法改正によって価格表示に税込み価格(内税)を表示することが義務付けられた。そこで,2001年までは税抜き価格を,2002年からは税込み価格を「価格」列として表示する結果(図1の色のついてない部分)を求めたい図2)⁠

図1 Itemsテーブル

図1 Itemsテーブル

図2 求めるべき結果

item_name| year | price
---------+------+-------
カップ   | 2000 | 500
カップ   | 2001 | 520
カップ   | 2002 | 630
カップ   | 2003 | 630
スプーン | 2000 | 500
スプーン | 2001 | 500
スプーン | 2002 | 525
スプーン | 2003 | 525
ナイフ   | 2000 | 600
ナイフ   | 2001 | 550
ナイフ   | 2002 | 577
ナイフ   | 2003 | 420

条件分岐問題の基礎ね。year 列の値を分岐の条件に使う,と。それで,あなたの回答は?

これです。はい!リスト1)⁠ この解のポイントはですね,UNIONの代わりにUNION ALLを使うことでソートを回避して性能改善も図っていることです注1)⁠条件が排他的だから問題ないわけです。

リスト1 問1に対するワイリーの解答

SELECT item_name, year, price_tax_ex AS price
  FROM Items
 WHERE year <= 2001
UNION ALL
SELECT item_name, year, price_tax_in AS price
  FROM Items
 WHERE year >= 2002;

イタタた…。


足の小指でもぶつけました?


いや,そうじゃなくて,あなたの解を見てアタマ痛くなったの! もう,先が思いやられるわ…。

注1)
ワイリーの言っていることは間違いではありません。UNIONは結果から重複行を削除するためにソートを行いますが,UNION ALLはソートをスキップします。今回は,年を基準に排他的な分岐を行っているため,UNIONもUNION ALLも結果が同値なため,互換可能です。

著者プロフィール

ミック

SI企業に勤務するDBエンジニア。主にデータウェアハウス業務に従事している。自身のサイト「リレーショナル・データベースの世界」でデータベースとSQLについての技術情報を公開している。『Web+DB Press』で「SQL緊急救命室」を連載中。

著書:『SQL ゼロからはじめるデータベース操作』(翔泳社,2010)『達人に学ぶ SQL徹底指南書』(翔泳社,2008)訳書:J.セルコ『SQLパズル 第2版』(翔泳社,2007)

Twitter:copinemickmack

SQL緊急救命室:サポートページ

コメント

コメントの記入