このトピックでは、PolarDB-X 1.0でサポートされているサブクエリの種類、およびPolarDB-X 1.0でサブクエリを使用する場合の制限と追加の考慮事項について説明します。
制限事項
ネイティブMySQLと比較して、サブクエリを使用する場合、PolarDB-X 1.0には次の制限があります。
- サブクエリはHAVING句では使用できません。 例:
SELECT name, AVG( quantity) tb1から グループ名 持っているAVG (数量) > 2 * ( セレクトAVG (数量) tb2から );
- サブクエリはJOIN ON句では使用できません。 例:
SELECT * FROM tb1 p JOIN tb2 s on (p.id=s.id and p.quantity>All(select quantity from tb3))
- ROWサブクエリとスカラサブクエリは、等号 (=) の前後に同時に配置することはできません。 例:
select * from tb1 where row(id, name) = (select id, name from tb2)
- UPDATE SET句ではサブクエリを使用できません。 例:
UPDATE t1 SET c1 = (SELEc2 FROM t2 WHERE t1.c1 = t2.c1) LIMIT 10
追加の考慮事項
PolarDB-X 1.0では、一部のサブクエリはAPPLY演算子のみを使用して実行でき、非効率なクエリになります。 次の非効率的なSQL文を避けます。
- WHERE句にOR演算子とサブクエリの両方が含まれるSQL文。 外部テーブルのデータに基づいて実行効率が低下します。 例:
Efficient: select * from tb1 where id in (tb2からselect id) 効率的: select * from tb1でid in (tb2からidを選択) およびid>3 非効率: select * from tb1 id in (tb2からselect id) またはid>3
- 相関アイテムが関数で使用されるか、または非等号とともに使用される相関サブクエリ。 例:
Efficient: 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からidを選択してください! =b.name) 非効率: 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: 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文には複数の相関レベルがあります。 各サブクエリ内の相関アイテムは、上位レベルとのみ相関する。 そのようなステートメントは効率的です。
効率的: select * from tb1 a where id in (tb2 bから選択したid) 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句を含むサブクエリ。 関連付けられたアイテムがグループ化列に関連付けられていることを確認します。 例:
- SQLサブクエリには、集計関数と相関アイテムが含まれます。
b.pk
の相関項目は、pk
グループ化列に相関される。 このようなSQL文は効率的です。効率的: 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 1.0は、次のタイプのサブクエリをサポートしています。
- サブクエリを使用した比較
サブクエリを使用する比較は、比較演算子を使用するサブクエリを示します。 これらのサブクエリは一般的に使用されます。
- 構文:
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を含むサブクエリ
- 構文:
operand comparison_operator ANY (サブクエリ) operand comparison_operator ALL (サブクエリ) オペランドIN (サブクエリ) オペランドNOT IN (サブクエリ) オペランドEXISTS (サブクエリ) オペランドNOT EXISTS (サブクエリ) comparison_operator:= > < >= <= <> ! =
- 例
- ANY: サブクエリによって返された行がanyより前の式を満たす場合、TRUEが返されます。 それ以外の場合は、FALSE が返されます。
- ALL: サブクエリによって返されたすべての行がallの前の式を満たす場合、TRUEが返されます。 それ以外の場合は、FALSE が返されます。
- IN: INがサブクエリの前に使用されている場合、INは
=ANY
と同等です。 例: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: サブクエリが行を返す場合、TRUEが返されます。 それ以外の場合は、FALSE が返されます。 例:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
説明 サブクエリに行が含まれている場合、サブクエリにNULL行のみが含まれている場合でも、WHERE条件はTRUEを返します。 - NOT EXISTS: サブクエリが行を返す場合、FALSEが返されます。 それ以外の場合は、TRUE が返されます。
- 構文:
- ROWサブクエリ
- ROWサブクエリは、以下の比較演算子をサポートします:
comparison_operator: = > < >= <= <> ! =<=>
- 例:
t1からのSELECT * 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
などのエイリアスが必要です。 - 派生テーブルは、スカラー、列、行、またはテーブルを返すことができます。
- 派生テーブルにサブクエリを関連付けることはできません。 派生テーブルに外部クエリの外部テーブルへの参照を含めることはできません。
- 派生テーブルには、前のステートメントの
- データを準備する:
- 構文: