ORACLE 中UNION ,UNION ALL ,MINUS,INTERSECT区别

SQL联合查询详解:UNION与UNION ALL的应用
本文深入解析SQL中的UNION和UNION ALL关键字的使用方法,通过实际例子展示如何将两个SELECT语句的结果合并,并讨论它们在结果集处理上的差异。文章还介绍了如何在联合查询中使用ORDER BY子句对结果进行排序,以及如何正确地应用这些关键字以避免潜在的错误。

如果我们需要将两个select语句的结果作为一个整体显示出来,我们就需要用到union或者union all关键字。union(或称为联合)的作用是将多个结果合并在一起显示出来。

union和union all的区别是,union会自动压缩多个结果集合中的重复结果,而union all则将所有的结果全部显示出来,不管是不是重复。



Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;

Union All:对两个结果集进行并集操作,包括重复行,不进行排序;

Intersect:对两个结果集进行交集操作,不包括重复行,同时进行默认规则的排序;

Minus:对两个结果集进行差操作,不包括重复行,同时进行默认规则的排序。

可以在最后一个结果集中指定Order by子句改变排序方式。



例如:

Java代码 复制代码
  1. select employee_id,job_id from employees   
  2. union   
  3. select employee_id,job_id from job_history  
select employee_id,job_id from employees
union
select employee_id,job_id from job_history




以上将两个表的结果联合在一起。这两个例子会将两个select语句的结果中的重复值进行压缩,也就是结果的数据并不是两条结果的条数的和。如果希望即使重复的结果显示出来可以使用union all,例如:

2.在oracle的scott用户中有表emp

Java代码 复制代码
  1. select * from emp where deptno >= 20  
  2. union all   
  3. select * from emp where deptno <= 30  
select * from emp where deptno >= 20
union all
select * from emp where deptno <= 30

这里的结果就有很多重复值了。



有关union和union all关键字需要注意的问题是:

union 和 union all都可以将多个结果集合并,而不仅仅是两个,你可以将多个结果集串起来。
使用union和union all必须保证各个select 集合的结果有相同个数的列,并且每个列的类型是一样的。但列名则不一定需要相同,oracle会将第一个结果的列名作为结果集的列名。例如下面是一个例子:

Java代码 复制代码
  1. select empno,ename from emp   
  2. union   
  3. select deptno,dname from dept   
select empno,ename from emp
union
select deptno,dname from dept 


我们没有必要在每一个select结果集中使用order by子句来进行排序,我们可以在最后使用一条order by来对整个结果进行排序。例如:

Java代码 复制代码
  1. select empno,ename from emp   
  2. union   
  3. select deptno,dname from dept   
  4. order by ename;   
### SQL 中 UNIONUNION ALLINTERSECT MINUS区别及用法 #### 1. UNION `UNION` 操作符用于合并两个或多个 `SELECT` 语句的结果集。要求每个 `SELECT` 语句的列数必须相同,且对应列的数据类型也必须一致[^2]。此外,`UNION` 会自动去除重复的行。 **语法:** ```sql SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2; ``` **示例:** ```sql SELECT empno, ename FROM emp WHERE deptno = 30 UNION SELECT empno, ename FROM emp WHERE job = 'MANAGER'; ``` #### 2. UNION ALL `UNION ALL` 与 `UNION` 类似,但不会去除重复的行,因此性能通常优于 `UNION`[^5]。它将所有结果集中的数据全部显示出来,包括重复项。 **语法:** ```sql SELECT column_name(s) FROM table1 UNION ALL SELECT column_name(s) FROM table2; ``` **示例:** ```sql SELECT empno, ename FROM emp WHERE deptno = 30 UNION ALL SELECT empno, ename FROM emp WHERE job = 'MANAGER'; ``` #### 3. INTERSECT `INTERSECT` 操作符返回两个查询结果集的交集,即同时存在于两个结果集中的记录。需要注意的是,`INTERSECT` 在某些数据库中不被支持(如 MySQL PostgreSQL),但在 Oracle SQL Server 中可用[^1]。 **语法:** ```sql SELECT column_name(s) FROM table1 INTERSECT SELECT column_name(s) FROM table2; ``` **示例:** ```sql SELECT empno FROM emp WHERE deptno = 30 INTERSECT SELECT empno FROM emp WHERE job = 'MANAGER'; ``` #### 4. MINUS `MINUS` 操作符返回第一个查询结果集中有但第二个查询结果集中没有的记录。与 `INTERSECT` 类似,`MINUS` 在某些数据库中也不被支持(如 MySQL PostgreSQL),但在 Oracle DB2 中可用。 **语法:** ```sql SELECT column_name(s) FROM table1 MINUS SELECT column_name(s) FROM table2; ``` **示例:** ```sql SELECT empno FROM emp WHERE deptno = 30 MINUS SELECT empno FROM emp WHERE job = 'MANAGER'; ``` #### 数据库兼容性总结 - `UNION` `UNION ALL`:在大多数现代关系型数据库管理系统中通用,包括 Oracle、MySQL、SQL Server、PostgreSQL DB2 等。 - `INTERSECT`:在 Oracle、SQL Server DB2 中可用,但在 MySQL PostgreSQL 中不直接支持。 - `MINUS`:在 Oracle DB2 中可用,但在 MySQL PostgreSQL 中不直接支持。对于不支持的数据库,可以通过其他方法(如 `LEFT JOIN` `WHERE` 子句)实现类似效果[^1]。 #### 使用场景 - **UNION**:当需要合并两个结果集并去重时使用。 - **UNION ALL**:当需要快速合并两个结果集且不需要去重时使用。 - **INTERSECT**:当需要获取两个结果集的交集时使用。 - **MINUS**:当需要获取第一个结果集中有但第二个结果集中没有的记录时使用。 ### 示例代码对比 以下为一个完整的示例,展示四种操作的区别: ```sql -- 表 A CREATE TABLE A (id INT); INSERT INTO A VALUES (1), (2), (3); -- 表 B CREATE TABLE B (id INT); INSERT INTO B VALUES (2), (3), (4); -- UNION SELECT id FROM A UNION SELECT id FROM B; -- UNION ALL SELECT id FROM A UNION ALL SELECT id FROM B; -- INTERSECT SELECT id FROM A INTERSECT SELECT id FROM B; -- MINUS SELECT id FROM A MINUS SELECT id FROM B; ``` #### 结果分析 - **UNION**:返回 `[1, 2, 3, 4]`。 - **UNION ALL**:返回 `[1, 2, 3, 2, 3, 4]`。 - **INTERSECT**:返回 `[2, 3]`。 - **MINUS**:返回 `[1]`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值