サブクエリ
MySQL 4.1 ではサブクエリのサポートが導入されたため、この章で説明する SQL を使用するには、MySQL 4.1 以降を使用する必要があります。
SELECT ステートメントは SQL クエリです。これまで見てきたすべての SELECT ステートメントは単純なクエリ、つまり単一のデータベース テーブルからデータを取得する単一のステートメントでした。
Query (クエリ) SQL ステートメントはすべてクエリです。ただし、この用語は通常、SELECT ステートメントを指します。
SQL では、サブクエリ、、つまり他のクエリ内にネストされたクエリ を作成することもできます。なぜこれを行うのでしょうか?この概念を理解する最良の方法は、いくつかの例を検討することです。
フィルタリングにサブクエリを使用する
この本のすべての章で使用されているデータベース テーブルはリレーショナル テーブルです (各テーブルと関係の説明については、付録 B を参照してください)。注文は 2 つのテーブルに保存されます。注文テーブルには、注文番号、顧客 ID、注文日を含む注文ごとに 1 行が保存されます。各注文の品目は、関連する orderitem テーブルに保存されます。注文テーブルには顧客情報は保存されません。顧客のIDのみを保存します。実際の顧客情報は、customers テーブルに保存されます。さて、商品 TNT2 を注文したすべての顧客をリストする必要がある場合、それをどのように取得すればよいでしょうか?具体的な手順を以下に示します。
(1) アイテム TNT2 を含むすべての注文の番号を取得します。
(2) 前のステップでリストされた注文番号を持つすべての顧客の ID を取得します。
(3) 前のステップで返されたすべての顧客 ID の顧客情報を取得します。
上記の各手順は、個別のクエリとして実行できます。ある SELECT ステートメントによって返された結果は、別の SELECT ステートメントの WHERE 句で使用できます。
サブクエリを使用して、3 つのクエリを 1 つのステートメントに結合することもできます。
最初の SELECT ステートメントの意味は明らかで、prod_id TNT2 を持つすべての注文アイテムについて、その order_num 列を取得します。出力には、この商品を含む 2 つの注文がリストされます。
入力:
select order_num from orderitems where prod_id = 'TNT2';
出力:
次に、注文 20005 と 20007 を持つ顧客 ID をクエリします。 IN 句を使用して、次の SELECT ステートメントを作成します。
入力:
select cust_id from orders where order_num in (20005,20007);
出力:
次に、最初のクエリ (注文番号を返すクエリ) をサブクエリに変更して、2 つのクエリを結合します。次の SELECT ステートメントを見てください:
入力:
select cust_id from orders where order_num in (select order_num from orderitems where prod_id = 'TNT2');
出力:
分析: SELECT ステートメントでは、サブクエリは常に内側から外側に処理されます。上記の SELECT ステートメントを処理するとき、MySQL は実際に 2 つの操作を実行します。
まず、次のクエリを実行します:
select order_num from orderitems where prod_id = 'TNT2';
このクエリは 2 つの注文番号 20005 と 20007 を返します。これら 2 つの値は、IN 演算子に必要なカンマ区切り形式で外側のクエリの WHERE 句に渡されます。外側のクエリは次のようになります:
select cust_id from orders where order_num in (20005,20007);
ご覧のとおり、出力は正しく、前にハードコーディングされた WHERE 句によって返された値と同じ値です。
サブクエリを含む書式設定された SQL SELECT ステートメントは、特に複雑な場合、読み取りやデバッグが困難になることがあります。上記のようにサブクエリを複数の行に分割し、適切にインデントすると、サブクエリの使用が大幅に簡素化されます。
これで、アイテム TNT2 を注文したすべての顧客の ID を取得しました。次のステップは、これらの顧客 ID の顧客情報を取得することです。 2 つの列を取得する SQL ステートメントは次のとおりです:
入力:
select cust_name,cust_contact from customers where cust_id in (10001,10004);
これらの顧客 ID をハードコーディングする代わりに、WHERE 句をサブクエリに変換できます:
入力:
select cust_name,cust_contact from customers where cust_id in(select cust_id from orders where order_num in(select order_num from orderitems where prod_id = 'TNT2'));
出力:
分析:上記の SELECT ステートメントを実行するには、MySQL は実際に 3 つの SELECT ステートメントを実行する必要があります。最も内側のサブクエリは、外側のサブクエリの WHERE 句で使用される順序番号のリストを返します。外側のサブクエリは、最も外側のクエリの WHERE 句で使用される顧客 ID のリストを返します。最も外側のクエリは必要なデータを返します。
WHERE 句でサブクエリを使用すると、強力で柔軟な SQL ステートメントを作成できることがわかります。ネストされたサブクエリの数に制限はありませんが、実際の使用ではパフォーマンスの制限により、あまりにも多くのサブクエリをネストすることはできません。
列は一致する必要があります (ここに示すように) WHERE 句でサブクエリを使用する場合、SELECT ステートメントに WHERE 句と同じ数の列があることを確認する必要があります。通常、サブクエリは単一の列を返して照合しますが、必要に応じて複数の列を使用できます。
サブクエリは通常 IN 演算子と組み合わせて使用されますが、等価 ( = )、不等号 ( ) などのテストにも使用できます。
サブクエリとパフォーマンス ここで指定したコードは機能し、望ましい結果が得られます。ただし、サブクエリの使用が、このタイプのデータ取得を実行する最も効率的な方法であるとは限りません。詳細については、この例が再度示されている第 15 章を参照してください。
【関連する推奨事項】
mysqlはサブクエリを使用して計算フィールドを作成します
mysqlの結合とリレーショナルテーブルとは何ですか?
結合を使用する理由と結合の作成方法
MySQLのWHERE句の重要性と複数のテーブルを結合する方法
以上がmysqlサブクエリとは何ですか?サブクエリを使用してフィルタリングするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。