ITコーディネータのシュウです。
じゃーん。また、ブルートレイン「北斗星」の写真を載せてみました。さぞかし、北斗星のファンか、鉄道マニアと思われるかもしれませんが、実はそういう訳ではありません。
帰宅途中の駅で、たくさんのマニアの方が写真を撮っていたので、ついつられて一緒になって写真を撮ってしまいました。私って、優柔不断というか、つられ易いタイプですよね。
ただ、そんなにマニアでもない私ですが、今年中にブルートレインがなくなってしまうという噂が真実だとすると、本当に残念に思ってしまうのでした。
<本日の題材>
EXISTS句
今日は、EXISTS句について取り上げてみます。
EXISTS句は、通常は相関副問合せ(親の問い合わせで処理された各レコードを副問い合わせにおいて評価する)のかたちで使用することが多いと思います。副問合せにおいて、結果行が1行以上存在すればTRUE、存在しなければFALSEを返し、TRUEの場合の行が結果として抽出されることになります。
記述の方法は以下のようになります。
SELECT 列名1, 列名2, … , 列名n
FROM 表名1
WHERE EXISTS
(SELECT ‘x’ FROM 表名2 -- ※
WHERE 表名1.列名x = 表名2.列名x
AND 他抽出条件)
※副問合せの中で SELECT ‘x’ のように固定値を使用しているのは、行がもどされるかどうかのみが判定されればよく、戻る列の値が何であっても問題はないこと、また定数を指定することで「存在有無の確認」であることをより明確に表現するという意味で、ORACLEなどでは慣習的に’x’などを指定することが多いようです。(SELECT * などでも問題はありません)
例として、以前使用したことのある、商品マスタと、売上テーブルを使用します。
まず、商品マスタのデータは以下:
SELECT * FROM 商品マスタ
ORDER BY 商品CD;
売上テーブルの「2014/11」のレコードが以下の場合:
SELECT *
FROM 売上テーブル
WHERE TO_CHAR(受注日,'YYYY-MM') = '2014-11'
ORDER BY 受注番号;
商品マスタのデータで、「2014/11」に受注のあった商品の一覧を抽出する場合、
SELECT 商品CD, 商品名
FROM 商品マスタ
WHERE EXISTS (SELECT 'x'
FROM 売上テーブル
WHERE 商品CD = 商品マスタ.商品CD
AND TO_CHAR(受注日,'YYYY-MM') = '2014-11')
ORDER BY 商品CD;
2014/11」に1回でも受注のあった商品が抽出されました。
逆に、「商品マスタのデータで、「2014/11」に一度も受注のなかった商品の一覧を抽出する場合、NOT EXISTS を使用します。
SELECT 商品CD, 商品名
FROM 商品マスタ
WHERE NOT EXISTS
(SELECT 'x'
FROM 売上テーブル
WHERE 商品CD = 商品マスタ.商品CD
AND TO_CHAR(受注日,'YYYY-MM') = '2014-11')
ORDER BY 商品CD;
SQL Serverでも同様です。
「2014/11」に1回でも受注のあった商品を抽出する場合:
SELECT商品CD,商品名
FROM dbo.商品マスタ
WHERE EXISTS
(SELECT 'x'
FROM dbo.売上テーブル
WHERE 商品CD = 商品マスタ.商品CD
AND SUBSTRING(CONVERT(VARCHAR, 受注日,112),1,6) = '201411') --※2
ORDER BY 商品CD;
※2:SQL Server 2012からは、FORMAT関数を使っても可能
「2014/11」に1度も受注のなかった商品を抽出する場合(FORMAT関数を使う):
SELECT商品CD,商品名
FROM dbo.商品マスタ
WHERE NOT EXISTS
(SELECT 'x'
FROM dbo.売上テーブル
WHERE 商品CD = 商品マスタ.商品CD
AND FORMAT(受注日,'yyyyMM') = '201411')
ORDER BY 商品CD;
結果はORACLEと同様になりました。
今日は以上まで
にほんブログ村