SQL入門
サブクエリ(副問合せ)

SQLの初心者向け入門解説、VBAからデータベースを扱うためのSQLを解説
最終更新日:2019-12-17

サブクエリ(副問合せ)


エクセルVBAでデータベースを扱うためのSQL入門です。
前回までで、基本的な部分については一通り説明しました。


今回は、より便利にSQLを使えるように副問合せ(サブクエリ)を解説します。
サブクエリが使えるようになると、SQLのすごさがより実感として分かってくるはずです。

すでに、他のテーブルのデータで追加/更新/削除、このなかでサブクエリを紹介しましたが、

・新規テーブルを追加 ・他のテーブルを基にデータを追加 ・他のテーブルを基にデータを更新 ・他のテーブルを基にデータを削除 ・他のテーブルを基にデータを追加/更新/削除の最後に
SELECT部分はサブクエリ(副問合せ)と呼ばれるものになります。
サブクエリについては、次回以降で詳しく解説します。

このように記載していました。
サブクエリについて、基本的な使い方を説明していきます。


使用するテーブル定義は以下になります。

全テーブル定義とテーブル自動作成VBA
・テーブル:m_customer ・テーブル:m_item ・テーブル:t_sales ・テーブル自動作成

サブクエリ(副問合せ)とは

まずクエリとは、「問い合わせ」の意味の英単語です。
データベースに対する問い合わせ言語としてSQLがあります。
つまり、クエリと言ったら、データベースではSQLの事になります。

サブクエリとは、クエリの中の一つの要素として、さらにクエリを入れたものです。
クエリを入れ子(ネスト)しての使い方になります。
SELECT、INSERT、UPDATE、DELETEの各命令の中の子要素として、SELECT命令を入れた書き方になります。
サブクエリの中にさらにサブクエリを入れられます、つまり、多段階のネストができます。

SELECTの結果は、複数のカラム(名前とデータ型)を持つ複数行のデータです。
これは、1つのテーブルと同じとみなすことができます。
複数のSELECT結果を統合(UNION,UNION ALL)
・集合演算:データの統合方法 ・SQLの集合演算について ・和集合:UNION ・全体集合:UNION ALL ・複数のSELECT結果を統合の最後に

SELECTの結果を1つのテーブルとしてSQLの中で使う事がサブクエリの基本的な使い方になります。
また、サブクエリの結果はデータリストとして使う事もできます。

FROM句でサブクエリを使う

SELECTのFROM句に1つのテーブルとしてサブクエリを使います。
SELECTとして実行できるものは、それを()括弧で囲う事で、1つのテーブルとして扱う事が出来ます。

codeごとの合計数を、SELECTの選択カラムとして追加します。

SELECT T.code,T.sales_date,T.item_count,TT.sum_count
  FROM t_sales T
  LEFT JOIN (SELECT code,SUM(item_count) AS sum_count
               FROM t_sales
               GROUP BY code) TT
  ON T.code = TT.code
一見すると難しそうに見えますが、サブクエリを1つのテーブルとしてみると単純なSQLになります。

SELECT T.code,T.sales_date,T.item_count
,TT.sum_count
 FROM t_sales T
 LEFT JOIN 
 (サブクエリ) TT
 ON T.code = TT.code
サブクエリを作成する場合は、単独のSELECTとして動作するかを先に確認すると良いでしょう。

SELECT code,SUM(item_count) AS sum_count
  FROM t_sales
  GROUP BY code
上記2つのSQLを合体させれば目的のサブクエリを組み込んだSQLが完成します。

WHERE句でサブクエリを使う

SELECTのWHERE句の1つの条件としてサブクエリを使います。
1カラムだけのSELECTの結果は、データリストとしてWHERE句の条件として使えます。

m_customerのaddressが「東京~」をt_salesから抽出します。
SELECT code,sales_date,item_count
 FROM t_sales T
 WHERE code IN (SELECT code FROM m_customer
                 WHERE address LIKE '東京%')
サブクエリで取得されるデータは、codeのリストになります。
このcodeのリストをINの中に指定しています。
これは、サブクエリを使わずにJOINで書くことができます。

SELECT T.code,T.sales_date,T.item_count
  FROM t_sales T
  INNER JOIN m_customer M
  ON T.code = M.code
 WHERE M.address LIKE '東京%'
WHERE句にあるサブクエリは、その多くはJOINで書き直すことができます。
WHERE句にサブクエリを追加しようと思ったときは、まずJOINで出来ないか良く検討してみると良いでしょう。

ただし、複数のテーブルを既にJOINしているSQLに、
後からさらに絞り込み条件を追加するような場合は、局所的な修正で済みとても便利な場合があります。

SELECTのカラムにサブクエリを使う

SELECTの列リストの1つとしてサブクエリを使います。
1カラムだけのSELECTの結果は、SELECTの選択列(カラム)として使用できます。

item_countの全合計を1つの列として追加します。

SELECT code,sales_date,item_count
 ,(SELECT SUM(item_count) AS sum_count FROM t_sales)
  FROM t_sales T
このサブクエリは汎用性がなく融通の利かないSQLと言えます。
これは、サブクエリを使わずにJOINで書くことができます。

SELECT T.code,T.sales_date,T.item_count,TT.sum_count
  FROM t_sales T
  LEFT JOIN (SELECT code,SUM(item_count) AS sum_count
               FROM t_sales) TT
SELECTの選択リストにあるサブクエリは、その多くはJOINで書き直すことができます。
選択リストにサブクエリを追加しようと思ったときは、JOINで出来ないか良く検討してください。

SELECTの選択リストにサブクエリを使う事は推奨できません。
代替方法が無い場合に限定して使うようにしてください。

UPDATAEでサブクエリを使う

「他のテーブルのデータで追加/更新/削除」で紹介したSQLです。
サブクエリで取得したデータをUPDATEのSET句で使用しています。

UPDATE t_sales_date SET
 item_amount = (SELECT SUM(item_price * item_count) AS item_amount
                 FROM t_sales T
                 WHERE t_sales_date.code = T.code
                   AND t_sales_date.sales_date = T.sales_date
                 GROUP BY code,sales_date)
WHERE code = '001'
サブクエリは1カラム限定、かつ、データ型を一致させるようにしてください。

DELETEでサブクエリを使う

「他のテーブルのデータで追加/更新/削除」で紹介したSQLです。
サブクエリで取得したデータをDELETEのWHERE句で使用しています。

DELETE FROM t_sales_date
 WHERE code || sales_date NOT IN 
      (SELECT code || sales_date
        FROM t_sales
        GROUP BY code,sales_date)
これは、SELECTのWHEREで使う場合と同じ使い方になります。

サブクエリ(副問合せ)の最後に

今回は、サブクエリの基本的な使い方を説明しました。
基本的な使い方として、
FROM句で使って他のテーブルとJOINする書き方と、
WHERE句のINに指定する書き方をマスターしておけば良いでしょう。

次回は、サブクエリを多段階にネストする書き方と、
複雑化したSQLへのコメントの書き方および整形について解説します。



同じテーマ「SQL入門」の記事

データの更新(UPDATE)
データの削除(DELETE)
他のテーブルのデータで追加/更新/削除
インデックスを作成して高速化(CREATE INDEX)
トランザクション処理
VBAクラスの全コード:トランザクション処理
サブクエリ(副問合せ)
サブクエリのネストとSQLコメント&整形
WITH句(共通テーブル式)
取得行数を限定するLIMIT句
分析関数(OVER句,WINDOW句)


新着記事NEW ・・・新着記事一覧を見る

数字(1~50)を丸付き数字に変換するVBA|VBA技術解説(2022-11-15)
TEXTAFTER関数(テキストの指定文字列より後ろの部分を返す)|エクセル入門(2022-11-14)
TEXTBEFORE関数(テキストの指定文字列より前の部分を返す)|エクセル入門(2022-11-14)
TEXTSPLIT関数(列と行の区切り記号で文字列を分割)|エクセル入門(2022-11-12)
LAMBDA以降の新関数はVBAで使えるか|VBA技術解説(2022-11-11)
WRAPCOLS関数(1次元配列を指定数の列で折り返す)|エクセル入門(2022-11-08)
WRAPROWS関数(1次元配列を指定数の行で折り返す)|エクセル入門(2022-11-08)
EXPAND関数(配列を指定された行と列に拡張する)|エクセル入門(2022-11-07)
TAKE関数(配列の先頭/末尾から指定行/列数を取得)|エクセル入門(2022-11-06)
DROP関数(配列の先頭/末尾から指定行/列数を除外)|エクセル入門(2022-11-06)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.Excelショートカットキー一覧|Excelリファレンス
7.並べ替え(Sort)|VBA入門
8.エクセルVBAでのシート指定方法|VBA技術解説
9.マクロって何?VBAって何?|VBA入門
10.ExcelマクロVBAの基礎を学習する方法|エクセルの神髄




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ