【发布时间】:2012-03-31 20:11:03
【问题描述】:
我注意到 Oracle 11 中 FULL OUTER JOIN 的一种奇怪行为。我从 HR 模式连接表,特别是 EMPLOYEES 和 DEPARTMENTS。
例如,以下查询返回 123 行:
SELECT * FROM employees e
FULL JOIN departments d ON e.department_id = d.department_id
但是,难以理解的是 - 当我在 select 子句中放置一组特定列时,查询将返回 122 行(缺少的行是针对没有分配部门的员工 - 另外返回的行与内连接相比,左连接):
SELECT first_name, last_name, department_name FROM employees e
FULL JOIN departments d on e.department_id = d.department_id
即使我计算行数,它也会返回 122 (COUNT(*))!!!到底是怎么回事? SELECT *和SELECT COUNT(*)有什么区别?
SELECT * ...的解释计划:
SELECT STATEMENT 122
VIEW VW_FOJ_0 122
HASH JOIN FULL OUTER 122
Access Predicates
E.DEPARTMENT_ID = D.DEPARTMENT_ID
TABLE ACCESS DEPARTMENTS FULL 27
TABLE ACCESS EMPLOYEES FULL 107
对于SELECT COUNT(*) ...:
SELECT STATEMENT 1
SORT AGGREGATE 1
VIEW VW_FOJ_0 122
HASH JOIN FULL OUTER 122
Access Predicates
E.DEPARTMENT_ID = D.DEPARTMENT_ID
INDEX DEPT_ID_PK FAST FULL SCAN 27
INDEX EMP_DEPARTMENT_IX FAST FULL SCAN 107
【问题讨论】:
-
如果您对这些列使用
union会发生什么?使用union all时有什么不同吗?如果你算上group by first_name, last_name, department_name,会得到什么? -
SELECT * FROM employees e FULL JOIN departments d on e.department_id = d.department_id返回 123 行,SELECT count(*) FROM employees e FULL JOIN departments d on e.department_id = d.department_id返回 122 行? -
是的,正是——这就是我发布这个问题的原因。
-
你能发布这些查询的解释计划吗?应该不同。
-
第一个计划中的基数也很奇怪——它是 122,但查询返回 123 行。