MaxCompute 支持 LEFT SEMI JOIN 和 LEFT ANTI JOIN 两种半连接语法,用于基于右表条件过滤左表数据。本文介绍其语法和使用示例。
功能介绍
MaxCompute支持如下SEMI JOIN操作:
LEFT SEMI JOIN
返回左表中在右表有匹配行的记录。等价于 IN SUBQUERY。
LEFT ANTI JOIN
返回左表中在右表无匹配行的记录。与NOT IN SUBQUERY 类似但不完全相同。
两种操作均支持 MAPJOIN HINT 以提升性能。
使用限制
右表只能在连接条件(ON子句)中引用,不能在WHERE或SELECT子句中引用。
示例数据
-- 创建一张分区表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
);
--向源表增加分区。
ALTER TABLE sale_detail ADD PARTITION (sale_date='2026', region='china');
ALTER TABLE sale_detail_sj ADD PARTITION (sale_date='2026', region='china');
--向源表追加数据。
INSERT INTO sale_detail PARTITION (sale_date='2026', region='china') VALUES ('s1','c1',100.1),('s2','c2',100.2),('s3','c3',100.3);
INSERT INTO sale_detail_sj PARTITION (sale_date='2026', region='china') VALUES ('s1','c1',100.1),('s2','c2',100.2),('s5','c2',100.2),('s2','c2',100.2);
使用示例
LEFT SEMI JOIN示例
查询sale_detail表中,total_price出现在sale_detail_sj表中的数据集。命令示例如下:
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 |
+-----------+-------------+-------------+-----------+--------+
| s1 | c1 | 100.1 | 2026 | china |
| s2 | c2 | 100.2 | 2026 | china |
+-----------+-------------+-------------+-----------+--------+仅返回 sale_detail 中能在 sale_detail_sj 找到相同 total_price 的行。
LEFT ANTI JOIN 示例
查询sale_detail表中,total_price没有出现在sale_detail_sj表中的数据集。命令示例如下:
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 | 2026 | china |
+-----------+-------------+-------------+-----------+--------+仅返回 sale_detail 中无法在 sale_detail_sj 找到相同 total_price 的行。