このトピックでは、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は、相関レベルにわたって相関している。 - SQL文には複数の相関レベルがあります。 各サブクエリ内の相関アイテムは、上位レベルとのみ相関する。 サブクエリを含むステートメントは効率的です。 次のコードブロックは、ステートメントの指定方法の例を示しています。
- 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);
- SQLサブクエリには、集計関数と相関アイテムが含まれます。 相関アイテム
サポートされるサブクエリ
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行のみを返します。 複数の行が返されると、エラーが報告されます。 - サブクエリによって返される
col3とcol4は、プライマリテーブルのcol1とcol2に等しくなります。
- サブクエリ
- ROWサブクエリは、次の比較演算子をサポートします。
- 相関サブクエリは、外部クエリに表示されるテーブルへの参照を含むサブクエリです。 次のコードブロックは、相関サブクエリの使用方法の例を示しています。
SELECT * からt1 WHERE column1 = ANY (SELECT column1 FROM t2) WHERE t2.column2 = t1.column2);この例では、サブクエリにt1テーブルとその列column2が含まれていません。 この場合、サブクエリは外部クエリのテーブルを参照します。
- 派生テーブル (FROM句のサブクエリ)
派生テーブルは、FROM句で指定されたサブクエリです。
- SELECT構文
... FROM (サブクエリ) [AS] tbl_name... - 例:
- データを準備します。
次のステートメントを実行して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; - 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;説明- 派生テーブルには、例で
t1などのエイリアスが指定されている必要があります。 - 派生テーブルは、スカラー、列、行、またはテーブルを返すことができます。
- 派生テーブルにサブクエリを関連付けることはできません。 派生テーブルに外部クエリの外部テーブルへの参照を含めることはできません。
- 派生テーブルには、例で
- データを準備します。
- SELECT構文