ODPS JOIN(MaxComputer) 与 Oracle JOIN 用法对比

目录

    • [一、基本 JOIN 类型](#一、基本 JOIN 类型)
      • [1. 单独一个 `JOIN` 等价于 `INNER JOIN`](#1. 单独一个 JOIN 等价于 INNER JOIN)
      • [2. `LEFT JOIN` / `RIGHT JOIN` 用法一致](#2. LEFT JOIN / RIGHT JOIN 用法一致)
      • [3. 关联键重复导致数据翻倍](#3. 关联键重复导致数据翻倍)
    • [二、ODPS 与 Oracle 的主要差异](#二、ODPS 与 Oracle 的主要差异)
      • [1. `(+)` 语法差异(重要)](#1. (+) 语法差异(重要))
      • [2. 半连接示例:`LEFT SEMI JOIN`](#2. 半连接示例:LEFT SEMI JOIN)
      • [3. `LEFT ANTI JOIN`(ODPS 特有)](#3. LEFT ANTI JOIN(ODPS 特有))
    • [三、多表 JOIN 顺序与优化](#三、多表 JOIN 顺序与优化)
    • 四、完整示例对比
    • 五、注意事项汇总

ODPS(MaxCompute)的 JOIN 语法与 Oracle 高度相似,但在一些细节上存在差异。以下将逐一说明。

一、基本 JOIN 类型

JOIN 类型 ODPS 语法 Oracle 语法 说明
内连接(INNER JOIN) JOININNER JOIN JOININNER JOIN 两者完全一致,只返回匹配的行。
左外连接(LEFT JOIN) LEFT JOINLEFT OUTER JOIN LEFT JOINLEFT OUTER JOIN 返回左表全部行,右表无匹配则为 NULL。
右外连接(RIGHT JOIN) RIGHT JOINRIGHT OUTER JOIN RIGHT JOINRIGHT OUTER JOIN 返回右表全部行,左表无匹配则为 NULL。
全外连接(FULL JOIN) FULL JOINFULL OUTER JOIN FULL JOINFULL OUTER JOIN 返回两表全部行,无匹配的一侧为 NULL。
交叉连接(CROSS JOIN) CROSS JOIN CROSS JOIN 返回笛卡尔积。
半连接 / 反连接 LEFT SEMI JOINLEFT ANTI JOIN(ODPS特有) EXISTS / NOT EXISTSIN / NOT IN ODPS 提供了专门的半连接语法,性能更好。

1. 单独一个 JOIN 等价于 INNER JOIN

sql 复制代码
-- ODPS 与 Oracle 一致
SELECT *
FROM table_a a
JOIN table_b b ON a.id = b.id;
-- 等价于
SELECT *
FROM table_a a
INNER JOIN table_b b ON a.id = b.id;

2. LEFT JOIN / RIGHT JOIN 用法一致

sql 复制代码
-- 左连接:保留左表所有记录
SELECT a.id, a.name, b.order_date
FROM customers a
LEFT JOIN orders b ON a.id = b.cust_id;

3. 关联键重复导致数据翻倍

无论 ODPS 还是 Oracle,只要 JOIN 的关联键在任一侧存在重复值,结果行数都可能翻倍(相当于一对多或多对多)。

sql 复制代码
-- 左表:id=1 出现两次
-- 右表:id=1 出现三次
-- 结果会产生 2×3 = 6 行 id=1 的记录
SELECT *
FROM left_table a
JOIN right_table b ON a.id = b.id;

注意 :若需避免数据翻倍,可提前去重或使用 DISTINCT、聚合函数等。

二、ODPS 与 Oracle 的主要差异

差异点 ODPS Oracle
旧式外连接语法((+) 不支持 (+) 语法 支持 WHERE a.id = b.id(+) 表示左外连接
半连接语法 LEFT SEMI JOIN / LEFT ANTI JOIN 无直接等价语法,需用 EXISTS / NOT EXISTS
JOIN 条件写法 必须使用 ON 子句,不支持 USING 支持 USING(column) 简化相同列名关联
NULL 比较行为 标准 SQL:NULL = NULL 结果为 NULL(不匹配) 相同
MAPJOIN 提示 支持 /*+ MAPJOIN(small_table) */ 优化小表 支持 /*+ USE_HASH(table) */ 等不同提示

1. (+) 语法差异(重要)

Oracle 允许在 WHERE 中使用 (+) 表示外连接,ODPS 不支持 ,必须使用标准的 LEFT/RIGHT/FULL JOIN

sql 复制代码
-- Oracle 旧式语法(不推荐,但可用)
SELECT *
FROM emp e, dept d
WHERE e.dept_id = d.dept_id(+);   -- 左外连接

-- ODPS 必须改写为:
SELECT *
FROM emp e
LEFT JOIN dept d ON e.dept_id = d.dept_id;

2. 半连接示例:LEFT SEMI JOIN

ODPS 的 LEFT SEMI JOIN 只返回左表中与右表匹配的记录,且不返回右表任何列(类似 EXISTS)。

sql 复制代码
-- ODPS:查询有订单的客户(不关心订单详情)
SELECT a.id, a.name
FROM customers a
LEFT SEMI JOIN orders b ON a.id = b.cust_id;

-- Oracle 等价写法:
SELECT a.id, a.name
FROM customers a
WHERE EXISTS (SELECT 1 FROM orders b WHERE a.id = b.cust_id);

3. LEFT ANTI JOIN(ODPS 特有)

返回左表中没有 匹配右表的记录(类似 NOT EXISTS)。

sql 复制代码
-- ODPS:查询从未下过订单的客户
SELECT a.id, a.name
FROM customers a
LEFT ANTI JOIN orders b ON a.id = b.cust_id;

三、多表 JOIN 顺序与优化

  • ODPS :优化器会自动重排 JOIN 顺序,但可通过 /*+ MAPJOIN(table) */ 强制将小表加载到内存。
  • Oracle :优化器基于统计信息选择最优顺序,也可使用 ORDERED 提示强制顺序。

MAPJOIN 示例(ODPS)

sql 复制代码
SELECT /*+ MAPJOIN(dim_date) */ *
FROM fact_sales a
JOIN dim_date b ON a.date_key = b.date_key;

四、完整示例对比

场景:员工表(emp)与部门表(dept)左连接,获取所有员工及其部门名称。

ODPS

sql 复制代码
SELECT e.empno, e.ename, d.dname
FROM emp e
LEFT JOIN dept d ON e.deptno = d.deptno;

Oracle(标准语法相同,也支持旧式):

sql 复制代码
-- 标准语法(推荐)
SELECT e.empno, e.ename, d.dname
FROM emp e
LEFT JOIN dept d ON e.deptno = d.deptno;

-- 旧式语法(仅 Oracle)
SELECT e.empno, e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno(+);

五、注意事项汇总

  1. 关联键重复导致数据膨胀:这是 SQL JOIN 的通用行为,并非 ODPS 或 Oracle 特有。务必检查关联键的唯一性。
  2. NULL 值处理NULL 与任何值(包括 NULL)比较均为 NULL,导致不匹配。若需将 NULL 视为相等,需使用 NVLCOALESCE 转换。
  3. 性能优化 :大表 JOIN 时,ODPS 中常用 MAPJOIN 提示;Oracle 中则常用 USE_HASHUSE_NL
  4. 字符串类型隐式转换:ODPS 对隐式转换限制较严,建议显式转换类型;Oracle 较宽松但可能引发索引失效。
  5. 分区表 JOIN :ODPS 中 JOIN 前尽量裁剪分区(WHERE partition_col = ...),可大幅减少数据扫描量。

ODPS 的 JOIN 核心功能与 Oracle 保持一致 ,只需注意 (+) 旧语法不支持、以及半连接语法的差异即可轻松迁移。建议统一使用标准 SQL 的 JOIN ... ON 语法。

相关推荐
一只小bit6 小时前
Redis哨兵机制、主从复制与集群搭建与维护
数据库·redis·bootstrap
zlwool12 小时前
图纸管理选型避坑指南
数据库·erp·设备erp·非标机械
小灰灰搞电子13 小时前
完全驾驭 Qt 与数据库:C++ ORM 框架 QxOrm 原理与实践指南
数据库·c++·qt
软件聚导航15 小时前
「聚小软 AI 助手」技术升级:从数据库检索到 RAG 知识库问答
前端·数据库·mysql·微信小程序·小程序·ai编程·rag
学习星球16 小时前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode
GoppViper16 小时前
RDF资源描述框架深度解析:语义Web的数据基石与实战逻辑
前端·数据库
2601_9621741716 小时前
Redis 简介
数据库·redis·wpf
夜雪一千17 小时前
MySQL 各种数据同步方案全梳理:从简单复制到异构同步实战
数据库·mysql
Highcharts.js18 小时前
Highcharts 下钻(Drilldown)柱状图 Demo
数据库·信息可视化·hbase·highcharts·drilldown·js模块·下钻图表
翼龙云_cloud18 小时前
阿里云国际渠道代理商:如何在ECS上部署Flask应用?
运维·数据库·阿里云·flask·云计算