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

MaxCompute:SEMI JOIN

最終更新日:Dec 09, 2024

MaxComputeは、LEFT SEMI JOINとLEFT ANTI JOINの2種類のSEMI JOIN操作をサポートしています。 SEMI JOIN操作では、右側のテーブルのデータは結果セットに表示されず、左側のテーブルのデータをフィルタリングするためにのみ使用されます。 これにより、クエリのパフォーマンスが向上します。 このトピックでは、LEFT SEMI JOINおよびLEFT ANTI JOINの使用方法について説明します。

説明

MaxComputeは、次のタイプのSEMI JOIN操作をサポートしています。

  • LEFT SEMI JOIN

    LEFT SEMI JOIN操作は、右側のテーブルに一致する行を持つ左側のテーブルから行を返します。 たとえば、左側のテーブルの1行のデータが指定された条件を満たし、そのデータが右側のテーブルに表示された場合、そのデータは結果セットに含まれます。

    MaxComputeでは、LEFT SEMI JOINの使用方法はIn SUBQUERYの使用方法と同様です。 インサブクエリの詳細については、「インサブクエリ」をご参照ください。 2つの操作のいずれかを選択できます。

  • LEFT ANTI JOIN

    LEFT ANTI JOIN操作は、右側のテーブルに一致する行がない左側のテーブルから行を返します。 たとえば、左側のテーブルの1行のデータが指定された条件を満たし、そのデータが右側のテーブルに表示されない場合、そのデータは結果セットに含まれます。

    MaxComputeでは、LEFT ANTI JOINの使用方法はNOT In SUBQUERYの使用方法と同様です。 NOT IN SUBQUERYの詳細については、「NOT IN SUBQUERY」をご参照ください。

SEMI JOINMAPJOIN hintsをサポートしています。 これらのヒントは、LEFT SEMI JOINLEFT ANTI JOINのパフォーマンスを向上させます。 MAPJOINヒントの詳細については、「MAPJOIN HINT」をご参照ください。

サンプルデータ

サンプルソースデータは、このトピックの例をよりよく理解するために提供されています。 次のステートメントでは、sale_detailテーブルとsale_detail_sjテーブルを作成し、テーブルにデータを挿入する方法について説明します。

-- Create a partitioned table named 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);

create table if not exists sale_detail_sj
(
shop_name     string,
customer_id   string,
total_price   double
)
partitioned by (sale_date string, region string);

-- Add partitions to the sale_detail table. 
alter table sale_detail add partition (sale_date='2013', region='china');
alter table sale_detail_sj add partition (sale_date='2013', region='china');

-- Insert data into the sale_detail table. 
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_sj partition (sale_date='2013', region='china') values ('s1','c1',100.1),('s2','c2',100.2),('s5','c2',100.2),('s2','c2',100.2);

sale_detailおよびsale_detail_sjテーブルのデータを照会します。サンプル文:

set odps.sql.allow.fullscan=true;
select * from sale_detail;
-- The following result is returned: 
+------------+-------------+-------------+------------+------------+
| 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      |
+------------+-------------+-------------+------------+------------+
select * from sale_detail_sj;
-- The following result is returned: 
+------------+-------------+-------------+------------+------------+
| shop_name  | customer_id | total_price | sale_date  | region     |
+------------+-------------+-------------+------------+------------+
| s1         | c1          | 100.1       | 2013       | china      |
| s2         | c2          | 100.2       | 2013       | china      |
| s5         | c2          | 100.2       | 2013       | china      |
| s2         | c2          | 100.2       | 2013       | china      |
+------------+-------------+-------------+------------+------------+
                

  • 例1: sale_detailテーブルからtotal_price列のデータを照会し、sale_detail_sjテーブルのtotal_price列に表示されるデータを取得します。 例:

    select * from sale_detail a left semi join sale_detail_sj b on a.total_price=b.total_price;

    次の応答が返されます。

    +------------+-------------+-------------+------------+------------+
    | shop_name  | customer_id | total_price | sale_date  | region     |
    +------------+-------------+-------------+------------+------------+
    | s2         | c2          | 100.2       | 2013       | china      |
    | s1         | c1          | 100.1       | 2013       | china      |
    +------------+-------------+-------------+------------+------------+

    sale_detailテーブルのtotal_price列の一部のデータがsale_detail_sjテーブルのtotal_price列に表示され、そのようなデータが返されます。

  • 例2: sale_detailテーブルからtotal_price列のデータを照会し、sale_detail_sjテーブルのtotal_price列に表示されないデータを取得します。 例:

    select * from sale_detail a left anti join sale_detail_sj b on a.total_price=b.total_price;

    次の応答が返されます。

    +------------+-------------+-------------+------------+------------+
    | shop_name  | customer_id | total_price | sale_date  | region     |
    +------------+-------------+-------------+------------+------------+
    | s3         | c3          | 100.3       | 2013       | china      |
    +------------+-------------+-------------+------------+------------+

    sale_detailテーブルのtotal_price列の一部のデータは、sale_detail_sjテーブルのtotal_price列には表されず、返されます。