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 JOIN
はMAPJOIN hints
をサポートしています。 これらのヒントは、LEFT SEMI JOIN
とLEFT 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列には表されず、返されます。