Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.2Mb


このページは機械翻訳したものです。

13.2.11.12 サブクエリーの制約

  • 一般に、テーブルを変更することも、サブクエリーの同じテーブルから選択することもできません。 たとえば、この制限は次の形式のステートメントに適用されます。

    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] IN subquery の場合、exprn タプル (行コンストラクタ構文を使用して指定します) にでき、サブクエリーは n タプルの行を返すことができます。 したがって、許可されている構文は、具体的には row_constructor [NOT] IN table_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 演算のシーケンスに、これを書き換えることによって実装されているためです。 この方法は、ALLANYSOME には使用できません。

  • 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 つは、このようなクエリーがソースとそのスレーブで異なる結果を生成できることです。