外部クエリと同じテーブルを参照するサブクエリの使い方を徹底解説
外部クエリにも登場するテーブルを参照するサブクエリとは?
サブクエリの中で、外部クエリ(外側のクエリ)にも登場するテーブルへの参照が含まれている場合、そのサブクエリは「相関サブクエリ(correlated subquery)」と呼ばれます。このようなケースでは、MySQLは内側のクエリから外側のクエリへという順序で評価を行います。
本記事では、実際のテーブルデータを使いながら、この仕組みを具体的なSQL文で分かりやすく解説します。
サンプルデータ:carsテーブル
理解を深めるために、以下のような「cars」テーブルのデータを使用します。
mysql> Select * from Cars; +------+--------------+---------+ | ID | Name | Price | +------+--------------+---------+ | 1 | Nexa | 750000 | | 2 | Maruti Swift | 450000 | | 3 | BMW | 4450000 | | 4 | VOLVO | 2250000 | | 5 | Alto | 250000 | | 6 | Skoda | 1250000 | | 7 | Toyota | 2400000 | | 8 | Ford | 1100000 | +------+--------------+---------+ 8 rows in set (0.02 sec)
例1:平均価格より安い車を抽出する
以下のクエリは、サブクエリ内で「Cars」テーブルを参照しており、このテーブルは外部クエリにも登場しています。
mysql> Select Name from cars WHERE Price < (SELECT AVG(Price) from Cars); +--------------+ | Name | +--------------+ | Nexa | | Maruti Swift | | Alto | | Skoda | | Ford | +--------------+ 5 rows in set (0.00 sec)
このクエリでは、MySQLはまず内側のサブクエリ「SELECT AVG(Price) FROM Cars」を評価し、全車の平均価格を算出します。その結果を受け取ってから、外側のクエリ「SELECT Name FROM Cars WHERE Price < …」が実行され、平均価格より安い車名だけが返されます。
例2:平均価格より高い車を抽出する
同様に、比較条件を逆にすれば、平均価格より高い車を取得することもできます。MySQLの評価順序も同じです。
mysql> Select Name from cars WHERE Price > (SELECT AVG(Price) from Cars); +--------+ | Name | +--------+ | BMW | | VOLVO | | Toyota | +--------+ 3 rows in set (0.00 sec)
まとめ:評価順序のポイント
- サブクエリが外部クエリと同じテーブルを参照していても問題なく動作します。
- MySQLは内側(サブクエリ)→外側(メインクエリ)の順に処理を進めます。
- サブクエリの結果(この例では平均価格)が、外側のWHERE句の比較条件に使われます。
このように、集計結果を条件として利用したい場面では、同じテーブルを参照するサブクエリが非常に便利です。ぜひ実際のデータベースでも試してみてください。
-
MySQLのCREATE TABLEクエリでCHAR_LENGTH()を使う方法
テーブル作成時にCHAR_LENGTH()を使用する MySQLでは、テーブル作成時にCHAR_LENGTH(カラム名)を使用することで、指定したカラムの文字数を自動的に計算して保存する「生成カラム(Generated Column)」を定義できます。これにより、データ挿入のたびに手動で文字数を数える必要がなくなります。 それでは、実際の例を見ながらテーブルを作成してみましょう。 mysql> create table DemoTable ( Id int NOT NULL AUTO_INCR
-
MySQLのテーブル名に「user」は使える?予約語エラーの原因と回避方法を解説
MySQLで「user」というテーブル名は使用できる?結論から言うと、「user」はMySQLの予約語(リザーブドワード)であるため、そのままテーブル名として使用することはできません。CREATE TABLE文などで「user」を使おうとすると、構文エラーが発生します。この問題を回避するには、主に以下の2つの方法があります。テーブル名を「users」など別の名前に変更するバッククォート(`)で「user」を囲んで使用するバッククォートを使った例どうしても「user」という名前を使いたい場合は、次のようにバッククォートで囲みます。mysql> create table `user` ( .