このページは機械翻訳したものです。
-
一般に、テーブルを変更することも、サブクエリーの同じテーブルから選択することもできません。 たとえば、この制限は次の形式のステートメントに適用されます。
DELETE FROM t WHERE ... (SELECT ... FROM t ...); UPDATE t ... WHERE col = (SELECT ... FROM t ...); {INSERT|REPLACE} INTO t (SELECT ... FROM t ...);
例外: 前述の禁止は、導出テーブルを使用している変更されたテーブルで、その導出テーブルが外部クエリーにマージされるのではなく実体化されている場合には適用されません。 (セクション8.2.2.4「マージまたは実体化を使用した導出テーブル、ビュー参照および共通テーブル式の最適化」を参照してください。) 例:
UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS dt ...);
導出テーブルからの結果は一時テーブルとして実体化されるため、
t
への更新が行われるまでに、t
内の関連する行がすでに選択されています。一般に、
NO_MERGE
オプティマイザヒントを追加することで、導出テーブルを実体化するオプティマイザに影響を与えることができます。 セクション8.9.3「オプティマイザヒント」を参照してください。 -
行比較演算は一部のみサポートされています。
の場合、expr
[NOT] INsubquery
expr
はn
タプル (行コンストラクタ構文を使用して指定します) にでき、サブクエリーはn
タプルの行を返すことができます。 したがって、許可されている構文は、具体的には
と表されますrow_constructor
[NOT] INtable_subquery
の場合、expr
op
{ALL|ANY|SOME}subquery
expr
はスカラー値にする必要があり、サブクエリーはカラムサブクエリーにする必要があります。複合カラム行を返すことはできません。
つまり、
n
タプルの行を返すサブクエリーの場合、次のものはサポートされています。(expr_1, ..., expr_n) [NOT] IN table_subquery
ただし、次のものはサポートされていません。
(expr_1, ..., expr_n) op {ALL|ANY|SOME} subquery
IN
の行比較がサポートされているのに、他はサポートされていない理由は、IN
が、=
比較およびAND
演算のシーケンスに、これを書き換えることによって実装されているためです。 この方法は、ALL
、ANY
、SOME
には使用できません。 MySQL 8.0.14 より前は、
FROM
句のサブクエリーを相関サブクエリーにすることはできません。 これらは、クエリー実行中にすべて実体化 (結果セットを生成するように評価) されるので、外部クエリーの行ごとに評価できません。 オプティマイザは、結果が必要になるまで実体化を遅延します。これにより、実体化を回避できます。 セクション8.2.2.4「マージまたは実体化を使用した導出テーブル、ビュー参照および共通テーブル式の最適化」を参照してください。-
MySQL は特定のサブクエリー演算子にサブクエリーの
LIMIT
をサポートしていません。mysql> SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1); ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
セクション13.2.11.10「サブクエリーのエラー」を参照してください。
-
MySQL では、サブクエリーで行をテーブルに挿入するなどのデータ変更の副作用があるストアドファンクションを参照できます。 たとえば、
f()
が行を挿入する場合、次のクエリーはデータを変更できます。SELECT ... WHERE x IN (SELECT f() ...);
この動作は、SQL 標準に対する拡張です。 MySQL では、オプティマイザによる処理の選択方法に応じて、特定のクエリーの実行ごとに
f()
が異なる回数実行される可能性があるため、非決定的な結果が生成される可能性があります。ステートメントベースレプリケーションまたは混合形式レプリケーションの場合、このような不確定の影響の 1 つは、このようなクエリーがソースとそのスレーブで異なる結果を生成できることです。