すべてのプロダクト
Search
ドキュメントセンター

PolarDB:サブクエリ

最終更新日:Jun 05, 2024

このトピックでは、PolarDB-Xでサポートされているサブクエリカテゴリについて説明します。 このトピックでは、PolarDB-Xのサブクエリの制限と注意事項についても説明します。

制限事項

ネイティブMySQLと比較して、PolarDB-Xはサブクエリに次の制限を提供します。

  • サブクエリはHAVING句では使用できません。 次のコードブロックは、HAVING句でサブクエリを使用する方法の例を示しています:
    SELECT name, AVG( quantity)
    tb1から
    グループ名
    持っているAVG (数量) > 2 * (
       セレクトAVG (数量)
       tb2から
     );
  • サブクエリはJOIN ON句では使用できません。 次のコードブロックは、JOIN on句でサブクエリを使用する方法の例を示しています。
    SELECT * FROM tb1 p JOIN tb2 s ON (p.id=s.id and p.quantity>All(select quantity from tb3))
  • PolarDB-Xは、等号 (=) を演算子として使用するスカラサブクエリのROW関数をサポートしていません。 次のコードブロックは、ROW関数の使用方法の例を示しています。
    SELECT * FROM tb1 WHERE row(id, name) = (select id, name from tb2)
  • UPDATE SET句ではサブクエリを使用できません。 次のコードブロックは、UPDATE SET句でサブクエリを使用する方法の例を示しています。
    UPDATE t1 SET c1 = (SELECT c2 FROM t2 WHERE t1.c1 = t2.c1) LIMIT 10

注意

PolarDB-Xでは、APPLY演算子のみを使用して特定のサブクエリを実行できます。 これは、クエリを非効率にする。 次の非効率的なSQL文を実行しないことを推奨します。

  • WHERE句にOR演算子とサブクエリが含まれるSQL文。 外部テーブルのデータに基づいて、SQL文の実行効率が低下します。 次のコードブロックは、SQL文を指定する方法の例を示しています。
    Efficient statement: select * from tb1 where id in (select id from tb2)
    効率的なステートメント: select * from tb1 id in (tb2からselect id) およびid>3
    非効率的なステートメント: select * from tb1 id in (tb2からselect id) またはid>3 
  • 相関アイテムが関数または非等号を含む相関サブクエリ。 次のコードブロックでは、相関サブクエリを含まないステートメントと、相関サブクエリを含むステートメントを指定する方法の例を示します。
    Efficient statement: select * from tb1 a where id in
          (tb2 b wher e a.name=b.nameからidを選択)
    非効率的なステートメント: select * from tb1 a where id in
          (UPPEがR(a.nameするtb2 bからidを選択)=b.name)
    非効率的なステートメント: select * from tb1 a where id in
          (a.de cimal_test=abs(b.de cimal_test) のtb2 bからidを選択)
    非効率的なステートメント: select * from tb1 a where id in
          (tb2 b wher e a.name!=b.nameからidを選択)
    非効率的なステートメント: select * from tb1 a where id in
          (tb2 b wher e a.name>=b.nameからidを選択) 
  • 相関アイテムがOR演算子を使用して他の条件と接続される相関サブクエリ。 次のコードブロックでは、相関サブクエリを含まないステートメントと、相関サブクエリを含むステートメントを指定する方法の例を示します。
    Efficientステートメント: select * from tb1 a where id in
          (tb2 bからidを選択します。e a.name=b.name
                                      およびb.date_test <''2015-12-02 ')
    非効率的なステートメント: select * from tb1 a where id in
          (tb2 bからidを選択します。e a.name=b.name
                                      またはb.date_test <''2015-12-02 ')
    非効率的なステートメント: select * from tb1 a where id in
          (tb2 bからidを選択します。e a.name=b.name
                                      またはb.date_test=a.date_test) 
  • 相関アイテムを含むスカラーサブクエリ。 次のコードブロックは、相関サブクエリを含まないステートメントと相関サブクエリを含むステートメントを指定する方法の例を示しています。
    Efficient statement: select * from tb1 a where id>
            (tb2 bからb.date_test<'2015-12-02 ')
    非効率的なステートメント: select * from tb1 a where id>
            (tb2 bからidを選択します。e a.name=b.name 
                                        およびb.date_test <''2015-12-02 ') 
  • 相関アイテムが相関レベルにまたがるサブクエリ。
    • SQL文には複数の相関レベルがあります。 各サブクエリ内の相関アイテムは、上位レベルとのみ相関する。 サブクエリを含むステートメントは効率的です。 次のコードブロックは、ステートメントの指定方法の例を示しています。
      Efficientステートメント: select * from tb1 a where id in(select id from tb2 b) 
              wher e a.name=b.nameと 
              存在する (tb3 cから名前を選択してb.address=c.address) 
    • SQL文には複数の相関レベルがあります。 表cのサブクエリの相関アイテムは、表aの列と相関する。 サブクエリを含むステートメントは非効率的です。 次のコードブロックは、ステートメントの指定方法の例を示しています。
      非効率的なステートメント: select * from tb1 a where id in (tb2 bからselect id from tb2 b 
              wher e a.name=b.nameと 
              存在します (tb3 cから名前を選択してくださいa.address=c.address) 
    説明 上記の例では、テーブルaテーブルbは同じ相関レベルに属し、テーブルbテーブルcは同じ相関レベルに属します。 表a表cは、相関レベルにわたって相関している。
  • GROUP BY句を含むサブクエリ。 GROUP BY句で指定されたグループ化列に相関項目が含まれていることを確認します。
    • SQLサブクエリには、集計関数と相関アイテムが含まれます。 相関アイテムb.pkは、pkグループ化列に相関される。 サブクエリを含むステートメントは効率的です。 次のコードブロックは、ステートメントの指定方法の例を示しています。
      Efficientステートメント: select * from tb1 a where exists 
          (tb2 bからpkを選択 
                      ここで、a.pk=b.pkおよびb.date_test='2003-04-05' 
                      グループによってpk); 
    • SQLサブクエリには、集計関数と相関アイテムが含まれます。 関連付けられている項目b.date_testは、pkグループ化列に関連付けられていません。 SQLサブクエリを含むステートメントは非効率的です。 次のコードブロックは、ステートメントの指定方法の例を示しています。
      非効率的なステートメント: select * from tb1 a where exists 
          (tb2 bからpkを選択 
                      ここで、a.date_test=b.date_testおよびb.date_test='2003-04-05' 
                      グループによってpk); 

サポートされるサブクエリ

PolarDB-Xは、次のタイプのサブクエリをサポートしています。

  • サブクエリを使用する比較は、比較演算子を使用するサブクエリを示します。 これらのサブクエリは最も一般的に使用されます。
    • 構文
      non_subquery_operand comparison_operator (サブクエリ)
      comparison_operator: = > < >= <= <> ! =<=> like 
    • select * from tb1 WHERE 'a' = (SELECT column1 FROM t1)
      説明 サブクエリは、比較演算子の右側にのみ指定できます。
  • ANY、ALL、IN/NOT IN、およびEXISTS/NOT EXISTSを含むサブクエリ
    • 構文
      オペランドcomparison_operator ANY (サブクエリ)
      operand comparison_operator ALL (サブクエリ)
      オペランドIN (サブクエリ)
      オペランドNOT IN (サブクエリ)
      オペランドEXISTS (サブクエリ)
      オペランドNOT EXISTS (サブクエリ)
      
      comparison_operator:= > < >= <= <> ! =
    • 例:
      • ANY: サブクエリによって返された行がANYより前の式を満たす場合、ANY演算子はTRUEを返します。 そうでなければ、ANYオペレータはFALSEを返す。
      • ALL: サブクエリによって返されたすべての行がallの前の式を満たす場合、ALL演算子はTRUEを返します。 そうでなければ、ANYオペレータはFALSEを返す。
      • IN: サブクエリの前にINが指定されている場合は、=ANYと同じ方法でINが使用されます。 次のコードブロックは、サブクエリの使用方法の例を示しています。
        SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);
        SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2); 
      • NOT IN: サブクエリの前にNOT INが指定されている場合、NOT INは <>ALLと同じ方法で使用されます。 次のコードブロックは、サブクエリの使用方法の例を示しています。
        SELECT s1 FROM t1 WHERE s1 <> ALL (SELECT s1 FROM t2);
        SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2); 
      • EXISTS: サブクエリが行を返す場合、EXISTS演算子はTRUEを返します。 そうでなければ、EXISTS演算子はFALSEを返す。 次のコードブロックは、サブクエリの使用方法の例を示しています。
        SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
        説明 サブクエリに行が含まれている場合、値がNULLの行のみが含まれている場合でも、WHERE句はTRUEを返します。
      • NOT EXISTS: サブクエリが行を返す場合、NOT EXISTS演算子はFALSEを返します。 サブクエリがNULLを返す場合、NOT EXISTS演算子はTRUEを返します。
  • 行サブクエリ
    • ROWサブクエリは、次の比較演算子をサポートします。
      comparison_operator: = > < >= <= <> ! =<=>
    • SELECT * FROM t1の例
      
        WHERE (col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10);
      SELECT * からt1
        WHERE ROW(col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10); 
      前の2つのSQL文も同様に実行できます。 t1テーブルのデータ行は、次の条件が満たされた場合にのみ返されます。
      • サブクエリSELECT col3, col4 FROM t2 WHERE id=10は1行のみを返します。 複数の行が返されると、エラーが報告されます。
      • サブクエリによって返されるcol3col4は、プライマリテーブルのcol1col2に等しくなります。
  • 相関サブクエリは、外部クエリに表示されるテーブルへの参照を含むサブクエリです。 次のコードブロックは、相関サブクエリの使用方法の例を示しています。
    SELECT * からt1
      WHERE column1 = ANY (SELECT column1 FROM t2)
                           WHERE t2.column2 = t1.column2); 

    この例では、サブクエリにt1テーブルとその列column2が含まれていません。 この場合、サブクエリは外部クエリのテーブルを参照します。

  • 派生テーブル (FROM句のサブクエリ)

    派生テーブルは、FROM句で指定されたサブクエリです。

    • SELECT構文
      ... FROM (サブクエリ) [AS] tbl_name... 
    • 例:
      1. データを準備します。

        次のステートメントを実行してt1テーブルを作成します。

        作成テーブルt1 (s1 INT、s2 CHAR(5) 、s3 FLOAT);
        t1値 (1、'1' 、1.0) に挿入します。t1値 (2、'2' 、2.0) に挿入します。
        次のステートメントを実行します。 クエリ結果は2, '2', 4.0です。
        SELECT sb1、sb2、sb3
          から (SELECT s1 AS sb1、s2 AS sb2、s3 * 2 AS sb3 FROM t1) AS sb
          どこsb1 > 1; 
      2. SUM関数によって処理されたグループ化データの平均値を照会します。

        次のSQL文を実行すると、エラーが報告され、結果は返されません。

        SELECT AVG(SUM(s1)) からt1グループBY s1;
        派生テーブルを含む次のステートメントを実行できます。 クエリ結果は1.5000です。
        SELECT AVG(sum_s1)
          FROM (SELECT SUM(s1) AS sum_s1
                からt1グループBY s1) AS t1; 
        説明
        1. 派生テーブルには、例でt1などのエイリアスが指定されている必要があります。
        2. 派生テーブルは、スカラー、列、行、またはテーブルを返すことができます。
        3. 派生テーブルにサブクエリを関連付けることはできません。 派生テーブルに外部クエリの外部テーブルへの参照を含めることはできません。