サブクエリとは、別のクエリ内にネストされた SELECT 文であり、別のクエリの結果セットに対してクエリを実行できます。一般的な使用例としては、集計値の計算、行の存在確認、別のクエリの結果に基づくデータフィルタリング、相関更新または相関削除の実行、JOIN 操作を簡素化して単一の値を返すこと、結果を外部クエリの派生テーブルとして使用すること、ソートやグループ化の基準を提供すること、および行単位の比較の実行などがあります。このトピックでは、MaxCompute がサポートするサブクエリの種類とその使用方法について説明します。
機能
MaxCompute は、次のタイプのサブクエリをサポートしています。
-
基本サブクエリは、クエリの
FROM句で使用され、派生テーブルとして機能します。クエリ内で複雑な計算やデータ変換に使用できます。 -
IN サブクエリは
WHERE句で使用し、サブクエリが返す値のセットに一致する行を外部クエリから選択します。 -
NOT IN サブクエリは
WHERE句で使用し、サブクエリの結果セットに一致しない行を外部クエリから選択します。 -
EXISTS サブクエリは、サブクエリが行を返すかどうかをテストします。実際のデータ自体を必要とせず、関連行の存在を確認する場合に役立ちます。
-
NOT EXISTS サブクエリは、サブクエリに一致する行がない外部クエリの行を選択します。
-
スカラーサブクエリは、単一の値 (単一の行と単一の列) を返します。通常、
SELECTリストや、WHEREまたはHAVING句の条件値として使用されます。
実行時に、クエリオプティマイザは、スカラー、IN、NOT IN、EXISTS、または NOT EXISTS サブクエリなどの一部のサブクエリを JOIN 操作に変換することがあります。MAPJOIN は効率的なブロードキャスト結合アルゴリズムです。サブクエリの結果が小さいテーブルであると判断した場合、サブクエリにヒントを追加して、MAPJOIN アルゴリズムを明示的に使用できます。詳細については、「SUBQUERY_MAPJOIN HINT」をご参照ください。
サンプルデータ
このトピックの例では、sale_detail という名前のパーティションテーブルを使用します。次の文を実行して、テーブルを作成し、データを入力します。
-- sale_detail という名前のパーティションテーブルを作成
CREATE TABLE IF NOT EXISTS sale_detail
(
shop_name string,
customer_id string,
total_price double
)
PARTITIONED BY (sale_date string, region string);
-- パーティションを追加
ALTER TABLE sale_detail ADD
PARTITION (sale_date='2013', region='china')
PARTITION (sale_date='2014', region='shanghai');
-- データを挿入
INSERT INTO sale_detail PARTITION (sale_date='2013', region='china')
VALUES ('s1','c1',100.1),('s2','c2',100.2),('s3','c3',100.3);
INSERT INTO sale_detail PARTITION (sale_date='2014', region='shanghai')
VALUES ('null','c5',null),('s6','c6',100.4),('s7','c7',100.5);
テーブル全体を表示するには:
SET odps.sql.allow.fullscan=true;
SELECT * FROM sale_detail;+------------+-------------+-------------+------------+------------+
| shop_name | customer_id | total_price | sale_date | region |
+------------+-------------+-------------+------------+------------+
| s1 | c1 | 100.1 | 2013 | china |
| s2 | c2 | 100.2 | 2013 | china |
| s3 | c3 | 100.3 | 2013 | china |
| null | c5 | NULL | 2014 | shanghai |
| s6 | c6 | 100.4 | 2014 | shanghai |
| s7 | c7 | 100.5 | 2014 | shanghai |
+------------+-------------+-------------+------------+------------+
基本サブクエリ
標準クエリはメインテーブルに対して操作を行いますが、クエリは別の select 文に対して操作を行うこともできます。 このようなクエリはサブクエリと呼ばれます。 from 句では、サブクエリはテーブルとして扱うことができ、join 操作を使用して他のテーブルやサブクエリと結合できます。 join 操作の詳細については、「JOIN」をご参照ください。
-
構文
select <select_expr> from (<select_statement>) [<sq_alias_name>]; -
パラメーター
-
select_expr: 必須。 クエリする通常列、パーティションキー列、または正規表現を
col1_name, col2_name, regular expression,...の形式で指定します。 -
select_statement:必須。サブクエリ文を指定します。形式の詳細については、「SELECT 構文」をご参照ください。
-
sq_alias_name:任意。サブクエリのエイリアスです。
table_name: 必須。メインテーブルの名前。
-
-
例
-
例 1:次のコマンドは、基本サブクエリ構文の例です。
set odps.sql.allow.fullscan=true; select * from (select shop_name from sale_detail) a;結果:
+------------+ | shop_name | +------------+ | s1 | | s2 | | s3 | | null | | s6 | | s7 | +------------+
-
例 2:
from句では、サブクエリをテーブルと見なして、他のテーブルやサブクエリとjoin操作を行うことができます。コマンドの例は次のとおりです。-- テーブルを作成し、JOIN 操作を実行します。 create table shop as select shop_name,customer_id,total_price from sale_detail; select a.shop_name, a.customer_id, a.total_price from (select * from shop) a join sale_detail on a.shop_name = sale_detail.shop_name;結果:
+------------+-------------+-------------+ | shop_name | customer_id | total_price | +------------+-------------+-------------+ | null | c5 | NULL | | s6 | c6 | 100.4 | | s7 | c7 | 100.5 | | s1 | c1 | 100.1 | | s2 | c2 | 100.2 | | s3 | c3 | 100.3 | +------------+-------------+-------------+
-
IN サブクエリ
in subquery は left semi join と同様に使用されます。
-
構文
-
形式 1
select <select_expr1> from <table_name1> where <select_expr2> in (select <select_expr3> from <table_name2>); -- この文は、次の LEFT SEMI JOIN 文と同じです。 select <select_expr1> from <table_name1> <alias_name1> left semi join <table_name2> <alias_name2> on <alias_name1>.<select_expr2> = <alias_name2>.<select_expr3>;説明select_expr2がパーティションキー列である場合、サブクエリselect <select_expr2> from <table_name2>は別のジョブで実行され、semi joinには変換されません。その実行結果はselect_expr2と比較されます。table_name1内のパーティションは、そのselect_expr2値が返された結果に含まれていない場合、読み取られません。これにより、パーティションプルーニングが有効なままであることが保証されます。 -
形式 2
MaxCompute は
in subqueryだけでなく、相関条件もサポートしています。サブクエリ内のwhere <table_name2_colname> = <table_name1>.<colname>句は相関条件です。MaxCompute 1.0 では、サブクエリ内のソーステーブルと外部クエリ内のソーステーブルの両方を参照する式はサポートされていませんでした。MaxCompute 2.0 はこの使用方法をサポートしており、このフィルター条件はon句のsemi joinの一部を構成します。select <select_expr1> from <table_name1> where <select_expr2> in (select <select_expr3> from <table_name2> where <table_name1>.<col_name> = <table_name2>.<col_name>);説明MaxCompute では、
join条件として使用されないin subquery(たとえば、where句の外にある場合や、where句内にあってもjoin条件に変換できない場合) は、semi joinに変換できず、その実行には個別のジョブを開始する必要があり、相関条件はサポートされません。 -
形式 3
前述の機能に基づき、MaxCompute は PostgreSQL の複数列のサポートと互換性があります。実装を複数のサブクエリに分割する場合と比較して、このアプローチは JOIN プロセスを 1 つ削減し、計算リソースを節約します。サポートされている複数列の用法は次のとおりです。
-
inの後に続く式には、単純な複数列の SELECT 文を使用できます。 -
inに続く式で集計関数を使用できます。詳細については、「集計関数」をご参照ください。 -
inの後の式は定数にできます。
-
-
-
パラメーター
-
select_expr1: 必須。 クエリする通常列、パーティションキー列、または正規表現を
col1_name, col2_name, regular expression,...の形式で指定します。 -
table_name1, table_name2: 必須。テーブルの名前です。
-
select_expr2, select_expr3: 必須。 table_name1 と table_name2 のマッピングされた列名です。
-
col_name: 必須。列の名前です。
-
-
使用上の注意
INでサブクエリを使用すると、NULL 値を持つ行はサブクエリの結果セットから自動的に削除されます。 -
例
-
例 1:形式 1 のサブクエリ構文を使用します。
set odps.sql.allow.fullscan=true; select * from sale_detail where total_price in (select total_price from shop);結果:
+-----------+-------------+-------------+-----------+--------+ | shop_name | customer_id | total_price | sale_date | region | +-----------+-------------+-------------+-----------+--------+ | s1 | c1 | 100.1 | 2013 | china | | s2 | c2 | 100.2 | 2013 | china | | s3 | c3 | 100.3 | 2013 | china | | s6 | c6 | 100.4 | 2014 | shanghai | | s7 | c7 | 100.5 | 2014 | shanghai | +-----------+-------------+-------------+-----------+--------+ -
例 2:形式 2 のサブクエリ構文を使用します。
set odps.sql.allow.fullscan=true; select * from sale_detail where total_price in (select total_price from shop where customer_id = shop.customer_id);結果:
+-----------+-------------+-------------+-----------+--------+ | shop_name | customer_id | total_price | sale_date | region | +-----------+-------------+-------------+-----------+--------+ | s1 | c1 | 100.1 | 2013 | china | | s2 | c2 | 100.2 | 2013 | china | | s3 | c3 | 100.3 | 2013 | china | | s6 | c6 | 100.4 | 2014 | shanghai | | s7 | c7 | 100.5 | 2014 | shanghai | +-----------+-------------+-------------+-----------+--------+ -
例 3: 複数列 SELECT 文の使用
-- 理解を容易にするため、ここでサンプルデータを再構築します。 create table if not exists t1(a bigint,b bigint,c bigint,d bigint,e bigint); create table if not exists t2(a bigint,b bigint,c bigint,d bigint,e bigint); insert into table t1 values (1,3,2,1,1),(2,2,1,3,1),(3,1,1,1,1),(2,1,1,0,1),(1,1,1,0,1); insert into table t2 values (1,3,5,0,1),(2,2,3,1,1),(3,1,1,0,1),(2,1,1,0,1),(1,1,1,0,1); -- シナリオ 1: `IN` の後の式は、単純な複数列の SELECT 文です。 select a, b from t1 where (c, d) in (select a, b from t2 where e = t1.e); -- 次の結果が返されます。 +------------+------------+ | a | b | +------------+------------+ | 1 | 3 | | 2 | 2 | | 3 | 1 | +------------+------------+ -- シナリオ 2: `IN` の後の式で集計関数を使用します。 select a, b from t1 where (c, d) in (select max(a), b from t2 where e = t1.e group by b having max(a) > 0); -- 次の結果が返されます。 +------------+------------+ | a | b | +------------+------------+ | 2 | 2 | +------------+------------+ -- シナリオ 3: `IN` の後の式は定数です。 select a, b from t1 where (c, d) in ((1, 3), (1, 1)); -- 次の結果が返されます。 +------------+------------+ | a | b | +------------+------------+ | 2 | 2 | | 3 | 1 | +------------+------------+
-
NOT IN サブクエリ
not in subquery は left anti join と似ていますが、同一ではありません。サブクエリが返す指定列に NULL 値が含まれている場合、not in 式は NULL と評価されます。これにより、where 句の条件が満たされなくなり、データは返されません。これは left anti join とは異なります。
-
構文
-
形式 1
select <select_expr1> from <table_name1> where <select_expr2> not in (select <select_expr3> from <table_name2>); -- この文は、次の LEFT ANTI JOIN 文と同じです。 select <select_expr1> from <table_name1> <alias_name1> left anti join <table_name2> <alias_name2> on <alias_name1>.<select_expr2> = <alias_name2>.<select_expr3>;説明select_expr2がパーティションキー列である場合、select <select_expr2> from <table_name2>サブクエリは別のジョブで実行され、anti joinには変換されません。その実行結果はselect_expr2の値と比較されます。table_name1のパーティションのうち、select_expr2の値が返された結果セットに含まれていないものは読み取られず、パーティションプルーニングの有効性が維持されます。 -
形式 2
MaxCompute は
NOT INサブクエリだけでなく、相関条件もサポートしています。サブクエリ内のwhere <table_name2_colname> = <table_name1>.<colname>句は相関条件です。MaxCompute 1.0 は、サブクエリ内のソーステーブルと外部クエリのソーステーブルの両方を参照する式をサポートしていませんでした。MaxCompute 2.0 はこの使用方法をサポートしています。このフィルター条件は、ANTI JOINのON条件の一部を構成します。select <select_expr1> from <table_name1> where <select_expr2> not in (select <select_expr2> from <table_name2> where <table_name2_colname> = <table_name1>.<colname>);説明MaxCompute は、
where句の外にある場合や、where句内にあってもjoin条件に変換できない場合など、not in subqueryがjoin条件として使用されないケースをサポートします。この場合、anti joinに変換することはできません。別のジョブを起動してサブクエリを実行する必要があり、相関条件はサポートされていません。 -
形式 3
前述の機能に基づき、MaxCompute は PostgreSQL の複数列のサポートと互換性があります。実装を複数のサブクエリに分割する場合と比較して、このアプローチは JOIN プロセスを 1 つ削減し、計算リソースを節約します。サポートされている複数列の用法は次のとおりです。
-
not inの後の式は、複数の列を返す単純な SELECT 文にすることができます。 -
not inに続く式で集計関数を使用できます。詳細については、「集計関数」をご参照ください。 -
not inに続く式は定数とすることができます。
-
-
-
パラメーター
-
select_expr1: 必須。 クエリする通常列、パーティションキー列、または正規表現を
col1_name, col2_name, regular expression,...の形式で指定します。 -
table_name1, table_name2: 必須。テーブルの名前です。
-
select_expr2, select_expr3: 必須。 table_name1 と table_name2 のマッピングされた列名です。
-
col_name: 必須。列の名前です。
-
-
使用上の注意
サブクエリで
NOT INを使用する場合、NULL 値を持つ行はサブクエリの結果セットから自動的に除外されます。 -
例
-
例 1:形式 1 のサブクエリ構文を使用します。
-- shop1 という名前の新しいテーブルを作成し、データを挿入します。 create table shop1 as select shop_name,customer_id,total_price from sale_detail; insert into shop1 values ('s8','c1',100.1); select * from shop1 where shop_name not in (select shop_name from sale_detail);結果:
+------------+-------------+-------------+ | shop_name | customer_id | total_price | +------------+-------------+-------------+ | s8 | c1 | 100.1 | +------------+-------------+-------------+ -
例 2:形式 2 のサブクエリ構文を使用します。
set odps.sql.allow.fullscan=true; select * from shop1 where shop_name not in (select shop_name from sale_detail where customer_id = shop1.customer_id);結果:
+------------+-------------+-------------+ | shop_name | customer_id | total_price | +------------+-------------+-------------+ | s8 | c1 | 100.1 | +------------+-------------+-------------+ -
例 3:
not in subqueryはjoin条件として使用されません。以下はコマンドの例です。set odps.sql.allow.fullscan=true; select * from shop1 where shop_name not in (select shop_name from sale_detail) and total_price < 100.3;where句にandが含まれているため、クエリはanti joinに変換できず、代わりに別のジョブでサブクエリとして実行されます。結果:
+------------+-------------+-------------+ | shop_name | customer_id | total_price | +------------+-------------+-------------+ | s8 | c1 | 100.1 | +------------+-------------+-------------+ -
例 4:サブクエリの結果に
NULL値が含まれている場合、データは返されません。次のコマンドに例を示します。-- sale という名前の新しいテーブルを作成し、データを挿入します。 create table if not exists sale ( shop_name string, customer_id string, total_price double ) partitioned by (sale_date string, region string); alter table sale add partition (sale_date='2013', region='china'); insert into sale partition (sale_date='2013', region='china') values ('null','null',null),('s2','c2',100.2),('s3','c3',100.3),('s8','c8',100.8); set odps.sql.allow.fullscan=true; select * from sale where shop_name not in (select shop_name from sale_detail);結果:
+------------+-------------+-------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | +------------+-------------+-------------+------------+------------+ +------------+-------------+-------------+------------+------------+ -
例 5: 複数列 SELECT 文の使用
-- 理解を容易にするため、ここでサンプルデータを再構築します。このデータは IN サブクエリ セクションのサンプルデータと同じです。 create table if not exists t1(a bigint,b bigint,c bigint,d bigint,e bigint); create table if not exists t2(a bigint,b bigint,c bigint,d bigint,e bigint); insert into table t1 values (1,3,2,1,1),(2,2,1,3,1),(3,1,1,1,1),(2,1,1,0,1),(1,1,1,0,1); insert into table t2 values (1,3,5,0,1),(2,2,3,1,1),(3,1,1,0,1),(2,1,1,0,1),(1,1,1,0,1); -- シナリオ 1: `NOT IN` の後の式は、単純な複数列の SELECT 文です。 select a, b from t1 where (c, d) not in (select a, b from t2 where e = t1.e); -- 次の結果が返されます。 +------------+------------+ | a | b | +------------+------------+ | 2 | 1 | | 1 | 1 | +------------+------------+ -- シナリオ 2: `NOT IN` の後の式で集計関数を使用します。 select a, b from t1 where (c, d) not in (select max(a), b from t2 where e = t1.e group by b having max(a) > 0); -- 次の結果が返されます。 +------------+------------+ | a | b | +------------+------------+ | 1 | 3 | | 3 | 1 | | 2 | 1 | | 1 | 1 | +------------+------------+ -- シナリオ 3: `NOT IN` の後の式は定数です。 select a, b from t1 where (c, d) not in ((1, 3), (1, 1)); -- 次の結果が返されます。 +------------+------------+ | a | b | +------------+------------+ | 1 | 3 | | 2 | 1 | | 1 | 1 | +------------+------------+
-
EXISTS サブクエリ
exists subquery を使用すると、サブクエリに 1 行以上のデータがある場合は True を返し、それ以外の場合は False を返します。
MaxCompute は、相関条件を含む where サブクエリのみをサポートします。exists subquery は left semi join として実装されています。
-
構文
select <select_expr> from <table_name1> where exists (select <select_expr> from <table_name2> where <table_name2_colname> = <table_name1>.<colname>); -
パラメーター
-
select_expr: 必須。 クエリする通常列、パーティションキー列、または正規表現を
col1_name, col2_name, regular expression,...の形式で指定します。 -
table_name1, table_name2: 必須。テーブルの名前です。
-
col_name: 必須。列の名前です。
-
-
例
set odps.sql.allow.fullscan=true; select * from sale_detail where exists (select * from shop where customer_id = sale_detail.customer_id); -- この文は、次の文と同じです。 select * from sale_detail a left semi join shop b on a.customer_id = b.customer_id;結果:
+------------+-------------+-------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | +------------+-------------+-------------+------------+------------+ | null | c5 | NULL | 2014 | shanghai | | s6 | c6 | 100.4 | 2014 | shanghai | | s7 | c7 | 100.5 | 2014 | shanghai | | s1 | c1 | 100.1 | 2013 | china | | s2 | c2 | 100.2 | 2013 | china | | s3 | c3 | 100.3 | 2013 | china | +------------+-------------+-------------+------------+------------+
NOT EXISTS サブクエリ
not exists サブクエリ を使用すると、サブクエリにデータが含まれていない場合は True が返され、それ以外の場合は False が返されます。
MaxCompute は、相関条件を含む where サブクエリのみをサポートします。not exists subquery は、left anti join として実装されます。
-
構文
select <select_expr> from <table_name1> where not exists (select <select_expr> from <table_name2> where <table_name2_colname> = <table_name1>.<colname>); -
パラメーター
-
select_expr: 必須。 クエリする通常列、パーティションキー列、または正規表現を
col1_name, col2_name, regular expression,...の形式で指定します。 -
table_name1, table_name2: 必須。テーブルの名前です。
-
col_name: 必須。列の名前です。
-
-
例
set odps.sql.allow.fullscan=true; select * from sale_detail where not exists (select * from shop where shop_name = sale_detail.shop_name); -- この文は、次の文と同じです。 select * from sale_detail a left anti join shop b on a.shop_name = b.shop_name;結果:
+------------+-------------+-------------+------------+------------+ | shop_name | customer_id | total_price | sale_date | region | +------------+-------------+-------------+------------+------------+ +------------+-------------+-------------+------------+------------+
スカラーサブクエリ
サブクエリが単一の行と単一の列を返す場合、スカラー演算でスカラー値として使用できます。クエリが 1 行のみを返す場合、結果を変更することなく、そのクエリを max または min 関数でラップできます。スカラーサブクエリは、複数列での使用もサポートしています。たとえば、スカラーサブクエリは SELECT リストで複数列の式として使用できますが、サポートされるのは等価式のみです。また、SELECT リストで BOOLEAN 式として使用することもできますが、これは等価比較の場合に限られます。where 句では、複数列の比較がサポートされていますが、これも等価比較のみです。
-
構文
-
形式 1
select <select_expr> from <table_name1> where (<select count(*) from <table_name2> where <table_name2_colname> = <table_name1>.<colname>) <scalar_operator> <scalar_value>; -- この文は、次の文と同じです。 select <table_name1>.<select_expr> from <table_name1> left semi join (select <colname>, count(*) from <table_name2> group by <colname> having count(*) <scalar_operator> <scalar_value>) <table_name2> on <table_name1>.<colname> = <table_name2>.<colname>;説明-
select count(*) from <table_name2> where <table_name2_colname> = <table_name1>.<colname>の出力は行セットです。このステートメントは 1 行 1 列のみを返します。そのため、スカラーとして扱うことができます。ただし、実装時には、可能な限りjoin演算に変換されます。 -
サブクエリは、コンパイル時に正確に 1 行と 1 列を返すことをコンパイラが確認できる場合にのみ、スカラーとして使用できます。これが実行時にのみ判断できる場合、コンパイラはエラーを返します。コンパイラが文を受け入れるには、次の 2 つの要件を満たす必要があります。
-
サブクエリの
SELECTリストは、テーブル値関数のパラメーターリストにない集計関数を使用しています。 -
集計関数を含むサブクエリに
group by句がありません。
-
-
-
形式 2
select (<select_statement>) from <table_name>;
-
-
パラメーター
-
select_expr: 必須。 クエリする通常列、パーティションキー列、または正規表現を
col1_name, col2_name, regular expression,...の形式で指定します。 -
table_name1, table_name2: 必須。テーブルの名前です。
-
col_name: 必須。列の名前です。
-
scalar_operator: 必須。 たとえば、より大きい (
>)、より小さい (<)、等しい (=)、以上 (>=)、または以下 (<=) です。 -
scalar_value:必須。スカラー値です。
-
select_statement: 必須。 サブクエリ文です。 フォーマット 2 を使用する場合、サブクエリは 1 行のみを返す必要があります。 詳細については、「SELECT 構文」をご参照ください。
-
-
制限事項
-
スカラーサブクエリは外部クエリの列を参照できますが、複数のスカラーサブクエリ文がネストされている場合、サブクエリは1つ外側のクエリの列のみ参照できます。-- 許可される操作。 select * from t1 where (select count(*) from t2 where t1.a = t2.a) = 3; -- 許可されない操作。ネストされたサブクエリは `t1.a` を参照していますが、これは直近の外部レイヤーではなく、2階層外のレイヤーを参照しているためです。 select * from t1 where (select count(*) from t2 where (select count(*) from t3 where t3.a = t1.a) = 2) = 3;
-
-
例
-
例 1:次のコマンドは、一般的な使用例です。
set odps.sql.allow.fullscan=true; select * from shop where (select count(*) from sale_detail where sale_detail.shop_name = shop.shop_name) >= 1;結果:
+------------+-------------+-------------+ | shop_name | customer_id | total_price | +------------+-------------+-------------+ | s1 | c1 | 100.1 | | s2 | c2 | 100.2 | | s3 | c3 | 100.3 | | null | c5 | NULL | | s6 | c6 | 100.4 | | s7 | c7 | 100.5 | +------------+-------------+-------------+ -
例 2: 複数列 SELECT 文を使用する。
-- 理解を容易にするため、ここでサンプルデータを再構築します。 create table if not exists ts(a bigint,b bigint,c double); create table if not exists t(a bigint,b bigint,c double); insert into table ts values (1,3,4.0),(1,3,3.0); insert into table t values (1,3,4.0),(1,3,5.0); -- シナリオ 1: SELECT 列は、複数列を持つスカラーサブクエリ式です。等価式のみがサポートされます。無効な使用法: `select (select a, b from t where c > ts.c) as (a, b), a from ts;` select (select a, b from t where c = ts.c) as (a, b), a from ts; -- 次の結果が返されます。 +------------+------------+------------+ | a | b | a2 | +------------+------------+------------+ | 1 | 3 | 1 | | NULL | NULL | 1 | +------------+------------+------------+ -- シナリオ 2: SELECT 列はブール式です。等価比較のみがサポートされます。無効な使用法: `select (a,b) > (select a,b from ts where c = t.c) from t;` select (a,b) = (select a,b from ts where c = t.c) from t; -- 次の結果が返されます。 +-------+ | _c0 | +-------+ | true | | false | +-------+ -- シナリオ 3: `WHERE` 句は複数列の比較をサポートします。等価比較のみがサポートされます。無効な使用法: `select * from t where (a,b) > (select a,b from ts where c = t.c);` select * from t where c > 3.0 and (a,b) = (select a,b from ts where c = t.c); -- 次の結果が返されます。 +------------+------------+------------+ | a | b | c | +------------+------------+------------+ | 1 | 3 | 4.0 | +------------+------------+------------+ select * from t where c > 3.0 or (a,b) = (select a,b from ts where c = t.c); -- 次の結果が返されます。 +------------+------------+------------+ | a | b | c | +------------+------------+------------+ | 1 | 3 | 4.0 | | 1 | 3 | 5.0 | +------------+------------+------------+ -
例 3:形式 2 のサブクエリ構文を使用します。
set odps.sql.allow.fullscan=true; select (select * from sale_detail where shop_name='s1') from sale_detail;結果:
+------------+-----------------+-----------------+-----------------+-----------------+ | _c0 | scalarsubquery1 | scalarsubquery2 | scalarsubquery3 | scalarsubquery4 | +------------+-----------------+-----------------+-----------------+-----------------+ | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | | s1 | c1 | 100.1 | 2013 | china | +------------+-----------------+-----------------+-----------------+-----------------+
-
関連トピック
サブクエリを過度に使用したり、非効率的に記述したりすると、特にビッグデータ環境では、クエリのパフォーマンスが低下する原因となることがあります。クエリ効率を向上させるには、一時テーブル、マテリアライズドビュー、または複数のサブクエリを JOIN 操作にリファクタリングするなどの代替案を検討することを推奨します。詳細については、「マテリアライズドビュー」および「JOIN」をご参照ください。