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

MaxCompute:サブクエリ

最終更新日:Aug 21, 2026

サブクエリとは、別のクエリ内にネストされた SELECT 文であり、別のクエリの結果セットに対してクエリを実行できます。一般的な使用例としては、集計値の計算、行の存在確認、別のクエリの結果に基づくデータフィルタリング、相関更新または相関削除の実行、JOIN 操作を簡素化して単一の値を返すこと、結果を外部クエリの派生テーブルとして使用すること、ソートやグループ化の基準を提供すること、および行単位の比較の実行などがあります。このトピックでは、MaxCompute がサポートするサブクエリの種類とその使用方法について説明します。

機能

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

  • 基本サブクエリ

    基本サブクエリは、クエリの FROM 句で使用され、派生テーブルとして機能します。クエリ内で複雑な計算やデータ変換に使用できます。

  • IN サブクエリ

    IN サブクエリは WHERE 句で使用し、サブクエリが返す値のセットに一致する行を外部クエリから選択します。

  • NOT IN サブクエリ

    NOT IN サブクエリは WHERE 句で使用し、サブクエリの結果セットに一致しない行を外部クエリから選択します。

  • EXISTS サブクエリ

    EXISTS サブクエリは、サブクエリが行を返すかどうかをテストします。実際のデータ自体を必要とせず、関連行の存在を確認する場合に役立ちます。

  • NOT 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 subqueryleft 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_name1table_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 subqueryleft 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 JOINON 条件の一部を構成します。

      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 subqueryjoin 条件として使用されないケースをサポートします。この場合、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_name1table_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 subqueryjoin 条件として使用されません。以下はコマンドの例です。

      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 subqueryleft 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」をご参照ください。