EXISTS句

ITコーディネータのシュウです。

IMG_0574_3

じゃーん。また、ブルートレイン「北斗星」の写真を載せてみました。さぞかし、北斗星のファンか、鉄道マニアと思われるかもしれませんが、実はそういう訳ではありません。
帰宅途中の駅で、たくさんのマニアの方が写真を撮っていたので、ついつられて一緒になって写真を撮ってしまいました。私って、優柔不断というか、つられ易いタイプですよね。
ただ、そんなにマニアでもない私ですが、今年中にブルートレインがなくなってしまうという噂が真実だとすると、本当に残念に思ってしまうのでした。

<本日の題材>
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;

exists_商品マスタ表示

売上テーブルの「2014/11」のレコードが以下の場合:

SELECT *
  FROM 売上テーブル
 WHERE TO_CHAR(受注日,'YYYY-MM') = '2014-11'
 ORDER BY 受注番号;

exists_150119受注

商品マスタのデータで、「2014/11」に受注のあった商品の一覧を抽出する場合、

SELECT 商品CD, 商品名
  FROM 商品マスタ
WHERE EXISTS (SELECT 'x'
                FROM 売上テーブル
               WHERE 商品CD = 商品マスタ.商品CD
                 AND TO_CHAR(受注日,'YYYY-MM') = '2014-11')
 ORDER BY 商品CD;

exists_1411受注のあった商品
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;

 not_exists_1411受注のなかった商品

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;

exists_1411受注のあった商品_sqlsv

※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;

not_exists_1411受注のなかった商品sqlsv

 結果はORACLEと同様になりました。

今日は以上まで

にほんブログ村 IT技術ブログへ
にほんブログ村

あけましておめでとうございます

ITコーディネータのシュウです。
IMG_0565_2

近くの神社に息子と寄ってみました。三が日は毎年人が多いので、ずらして行ったところ、あまり人も多くなくて、すぐにお詣りできました。
ラッキー!

新年あけましておめでとうございます。
旧年中は、大変お世話になりました。
つたない文章ながら、少しずつアクセス数も増えてきて、大変うれしく思っております。
今年も、へたりながらも頑張りますので、よろしくお願いします。

今日は以上まで

にほんブログ村 IT技術ブログへ
にほんブログ村