SQL 副問い合わせの基本を理解する
副問い合わせとはSQL
文の中に入れ子でSQL
文を指定することをいいます。
例えば下記のSQL
文は副問い合わせを使用しています。
SELECT 社員名
FROM 社員マスタ AS T1
WHERE EXISTS(
SELECT 1
FROM 売上明細 AS S1
WHERE T1.社員コード = S1.社員コード)
副問い合わせはWHERE
句だけでなく、SELECT
句やFROM
句でも使用することができます。
それぞれの句での副問い合わせの基本的な使い方を紹介します。
SELECT句での副問い合わせ
下記のような使い方をします。
SELECT 社員名
,(
SELECT MAX(S1.売上金額)
FROM 売上明細 S1
WHERE S1.社員コード = T1.社員コード
)
FROM 社員マスタ AS T1
副問い合わせのクエリではメインのクエリの値を使用することができます。上記SQL
ではT1.社員コード
をWHERE
句の条件に指定しています。
SELECT
句で副問い合わせをするには基本的に副問い合わせの取得結果が1件である必要があります。
SELECT
した結果が2件以上の場合はエラーになってしまいます。
テスト環境では取得結果が1件でエラーにならなかったが、本番環境では複数件取得してしまいエラーになってしまう、と言った場合もあるので注意が必要です。どんなデータでも1件のみ取得するような副問い合わせをすることが必要です。
FROM句での副問い合わせ
下記のような使い方をします。
SELECT MAX(T1.社員名) AS 社員名
,SUM(T2.売上金額) AS 確定売上金額
,SUM(T3.売上金額) AS 未確定売上金額
FROM 社員マスタ AS T1
LEFT JOIN
(
SELECT *
FROM 売上明細 S1
WHERE 状態区分 = 0
) T2
ON T1.社員コード = T2.社員コード
LEFT JOIN
(
SELECT *
FROM 売上明細 S1
WHERE 状態区分 = 1
) T3
ON T1.社員コード = T3.社員コード
GROUP BY T1.社員コード
SELECT
句の副問い合わせとは違い、メインのクエリの値を使用することができません。
上記SQL
では副問い合わせの中でT1.社員コード
を使用することはできません。
また、FROM
句での副問い合わせは、副問い合わせの取得結果が複数件でも問題ありません。
※今回は学習のために上記のようなわかりやすいSQLを例にしましたが、SQL CASE文で効率よく集計するテクニックでCASE
文を使った効率のよいSQL
を紹介しています。
WHERE句での副問い合わせ
下記のような使い方をします。
SELECT 社員名
FROM 社員マスタ AS T1
WHERE EXISTS
(
SELECT 1
FROM 売上明細 AS S1
WHERE T1.社員コード = S1.社員コード
)
--または
SELECT 社員名
FROM 社員マスタ AS T1
WHERE T1.社員コード IN
(
SELECT S1.社員コード
FROM 売上明細 AS S1
)
--または
SELECT 社員名
FROM 社員マスタ AS T1
WHERE T1.社員コード =
(
SELECT S1.社員コード
FROM 売上明細 AS S1
WHERE T1.社員コード = S1.社員コード
GROUP BY S1.社員コード
)
SELECT
句と同様に、副問い合わせのクエリではメインのクエリの値を使用することができます。
EXISTS
句はsql-exists
で説明したとおりです。
IN
句を指定した場合は、副問い合わせの結果が複数件でも問題ありません。
=
を指定した場合は、副問い合わせの結果が1件である必要があるので注意が必要です。