場合によっては、クエリの結果を別のクエリのフィールドとして使用したり、クエリ フィールドの条件として使用したりすることもできます。 たとえば、各製品の注文間隔を表示するとします。 この間隔を示すクエリを作成するには、各注文日をその製品の他の注文日と比較する必要があります。 これらの注文日を比較するには、クエリも必要です。 サブクエリを使用して、このクエリを メイン クエリ内に入れ子にすることができます。
サブクエリは、 式 または SQL ビューの 構造化照会言語 (SQL) ステートメントで記述できます。
この記事の内容
クエリの結果を別のクエリのフィールドとして使用する
サブクエリはフィールド エイリアスとして使用できます。 サブクエリの結果をメインクエリのフィールドとして使用する場合は、サブクエリをフィールドエイリアスとして使用します。
注: フィールドエイリアスとして使用するサブクエリは、複数のフィールドを返すことはできません。
サブクエリ フィールドエイリアスを使用すると、現在の行の他の値に依存する値を表示できます。サブクエリを使用しないと表示できません。
たとえば、各製品の注文間隔を確認する例に戻ります。 この間隔を決定するには、各注文日をその製品の他の注文日と比較する必要があります。 Northwind データベース テンプレートを使用して、この情報を表示するクエリを作成できます。
-
[ファイル] タブの [新規] をクリックします。
-
[ 使用可能なテンプレート] で、[ サンプル テンプレート] をクリックします。
-
[ Northwind] をクリックし、[ 作成] をクリックします。
-
Northwind Traders のページ ([スタートアップ画面] オブジェクト タブ) の指示に従ってデータベースを開き、[ログイン ダイアログ] ウィンドウを閉じます。
-
[作成] タブの [クエリ] グループで [クエリ デザイン] をクリックします。
-
[ クエリ ] タブをクリックし、[ 製品注文] をダブルクリックします。
-
[製品 ID] フィールドと [注文日] フィールドをダブルクリックして、クエリ デザイン グリッドに追加します。
-
グリッドの [製品 ID] 列の [並べ替え] 行で、[昇順] を選択します。
-
グリッドの [Order Date] 列の [並べ替え] 行で、[降順] を選択します。
-
グリッドの 3 番目の列で、[ フィールド ] 行を右クリックし、ショートカット メニューの [ ズーム ] をクリックします。
-
[ ズーム ] ダイアログ ボックスで、次の式を入力するか貼り付けます。
Prior Date: (SELECT MAX([Order Date])
FROM [Product Orders] AS [Old Orders]
WHERE [Old Orders].[Order Date] < [Product Orders].[Order Date]
AND [Old Orders].[Product ID] = [Product Orders].[Product ID])この式はサブクエリです。 各行について、サブクエリは、行に既に関連付けられている注文日よりも最近の注文日を選択します。 AS キーワード (keyword)を使用してテーブル エイリアスを作成する方法に注意してください。サブクエリの値を、メイン クエリの現在の行の値と比較できます。
-
グリッドの 4 列目の [フィールド ] 行に、次の式を入力します。
Interval: [Order Date]-[Prior Date]
この式は、サブクエリを使用して定義した前の日付の値を使用して、各注文日とその製品の前の注文日の間隔を計算します。
-
[デザイン] タブの [結果] グループで、[実行] をクリックします。
-
クエリは、製品名、注文日、前の注文日、および注文日の間隔の一覧を実行して表示します。 結果は、まず製品 ID (昇順) で並べ替え、次に Order Date (降順) で並べ替えられます。
-
注: 製品 ID はルックアップ フィールドであるため、既定では、Access では、実際の製品 ID ではなく、ルックアップ値 (この場合は製品名) が表示されます。 表示される値は変更されますが、並べ替え順序は変更されません。
-
-
Northwind データベースを閉じます。
クエリ フィールドの条件としてサブクエリを使用する
サブクエリをフィールド条件として使用できます。 サブクエリの結果を使用してフィールドに表示される値を制限する場合は、サブクエリをフィールド条件として使用します。
たとえば、営業担当者 ではない 従業員によって処理された注文の一覧を確認するとします。 この一覧を生成するには、各注文の従業員 ID と、営業担当者ではない従業員の従業員 ID の一覧を比較する必要があります。 このリストを作成し、それをフィールド条件として使用するには、次の手順に示すようにサブクエリを使用します。
-
Northwind.accdb を開き、そのコンテンツを有効にします。
-
ログイン フォームを閉じます。
-
[作成] タブの [その他] グループで、[クエリ デザイン] をクリックします。
-
[ テーブル ] タブで、[ 受注 と 従業員] をダブルクリックします。
-
[受注] テーブルで、[ 従業員 ID ] フィールド、 [注文 ID ] フィールド、および [注文日 ] フィールドをダブルクリックして、クエリ デザイン グリッドに追加します。 [従業員] テーブルで、[ ジョブ タイトル ] フィールドをダブルクリックしてデザイン グリッドに追加します。
-
[従業員 ID] 列の [ 抽出条件 ] 行を右クリックし、ショートカット メニューの [ ズーム ] をクリックします。
-
[ ズーム ] ボックスに、次の式を入力するか貼り付けます。
IN (SELECT [ID] FROM [Employees]
WHERE [Job Title]<>'Sales Representative')これはサブクエリです。 従業員が営業担当者の役職を持たないすべての従業員 ID を選択し、その結果セットをメインクエリに提供します。 次に、メインクエリによって、Orders テーブルの従業員 ID が結果セットに含まれているかどうかを確認します。
-
[デザイン] タブの [結果] グループで、[実行] をクリックします。
クエリが実行され、クエリ結果には、営業担当者ではない従業員によって処理された注文の一覧が表示されます。
サブクエリで使用できる一般的な SQL キーワード
サブクエリで使用できる SQL キーワードがいくつかあります。
注: このリストは網羅的ではありません。 データ定義キーワードを除き、サブクエリで有効な SQL キーワード (keyword)を使用できます。
-
すべての WHERE 句で ALL を使用して、サブクエリによって返されるすべての行と比較した場合に条件を満たす行を取得します。
たとえば、大学で学生データを分析しているとします。 学生は、少なくとも GPA を維持する必要があります。これは、専攻によって異なります。 メジャーとその最小 GPO は Majors という名前のテーブルに格納され、関連する学生情報は Student_Records というテーブルに格納されます。
その専攻を持つすべての学生が最小 GPA を超えるメジャー (およびその最小 GPO) の一覧を表示するには、次のクエリを使用します。
SELECT [Major], [Min_GPA]
FROM [Majors]
WHERE [Min_GPA] < ALL
(SELECT [GPA] FROM [Student_Records]
WHERE [Student_Records].[Major]=[Majors].[Major]); -
ANY WHERE 句で ANY を使用して、サブクエリによって返される行の少なくとも 1 つと比較した場合に条件を満たす行を取得します。
たとえば、大学で学生データを分析しているとします。 学生は、少なくとも GPA を維持する必要があります。これは、専攻によって異なります。 メジャーとその最小 GPO は Majors という名前のテーブルに格納され、関連する学生情報は Student_Records というテーブルに格納されます。
その専攻の学生が最小 GPA を満たしていないメジャー (およびその最小 GPO) の一覧を表示するには、次のクエリを使用できます。
SELECT [Major], [Min_GPA]
FROM [Majors]
WHERE [Min_GPA] > ANY
(SELECT [GPA] FROM [Student_Records]
WHERE [Student_Records].[Major]=[Majors].[Major]);注: また、同じ目的で SOME キーワード (keyword)を使用することもできます。SOME キーワード (keyword) は ANY と同義です。
-
EXISTS WHERE 句で EXISTS を使用して、サブクエリが少なくとも 1 行を返す必要があることを示します。 また、NOT で EXISTS の先頭を付けて、サブクエリが行を返してはならないことを示すこともできます。
たとえば、次のクエリは、少なくとも 1 つの既存の注文で見つかった製品の一覧を返します。
SELECT *
FROM [Products]
WHERE EXISTS
(SELECT * FROM [Order Details]
WHERE [Order Details].[Product ID]=[Products].[ID]);NOT EXISTS を使用すると、クエリは、少なくとも 1 つの既存の注文で見つからない製品の一覧を返します。
SELECT *
FROM [Products]
WHERE NOT EXISTS
(SELECT * FROM [Order Details]
WHERE [Order Details].[Product ID]=[Products].[ID]); -
インチ WHERE 句で IN を使用して、メイン クエリの現在の行の値が、サブクエリから返されるセットの一部であることを確認します。 また、IN の先頭に NOT を付けて、メイン クエリの現在の行の値が、サブクエリから返されるセットの一部でないことを確認することもできます。
たとえば、次のクエリは、営業担当者ではない従業員によって処理された注文の一覧 (注文日あり) を返します。
SELECT [Order ID], [Order Date]
FROM [Orders]
WHERE [Employee ID] IN
(SELECT [ID] FROM [Employees]
WHERE [Job Title]<>'Sales Representative');NOT IN を使用すると、次のように同じクエリを作成できます。
SELECT [Order ID], [Order Date]
FROM [Orders]
WHERE [Employee ID] NOT IN
(SELECT [ID] FROM [Employees]
WHERE [Job Title]='Sales Representative');