Oracle中的交差并集

目录

一、并集

二、交集

三、差集


一、并集

UNION ALL/UNION是一种用于合并两个或多个SELECT语句结果集的操作符。UNION ALL会将两个SELECT语句的结果集按照列的顺序合并,并保留重复的行,而UNION会将两个SELECT语句的结果集按照列的顺序合并,并去除重复的行。

语法如下:

--UNION ALL
SELECT column1, column2, ... FROM table1
UNION ALL
SELECT column1, column2, ... FROM table2;
--UNION 
SELECT column1, column2, ... FROM table1
UNION
SELECT column1, column2, ... FROM table2;

column1、column2等表示要查询的列名,table1、table2等表示要查询的表名或视图名。

使用UNION ALL/UNION 时,需要注意以下几点:

1. 要合并的SELECT语句中的列数必须相同,且对应的列类型和顺序也必须相同。

2. UNION ALL/UNION会将两个SELECT语句的结果集合并成一个结果集,因此,两个SELECT语句中的列名必须相同,否则会出现错误。

3. UNION ALL会保留重复的行,如果不想保留重复的行,可以使用UNION操作符

4. UNION ALL可以合并多个SELECT语句的结果集,只需要将每个SELECT语句用UNION ALL/UNION 连接即可。

下面是合并两个表的示例:

--UNION ALL
SELECT column1, column2, column3 FROM table1
UNION ALL
SELECT column1, column2, column3 FROM table2;
--UNION 
SELECT column1, column2, column3 FROM table1
UNION
SELECT column1, column2, column3 FROM table2;

UNION ALL语句会将table1和table2中的数据按照列的顺序合并成一个结果集,并保留重复的行,UNION 语句是去除重复的行。

比如两个数集:

A={1,2,3,4,5};B={1,3,6,9,4};

那么:

A UNION B={1,2,3,4,5,6,9},去重重复的数据;

A UNION ALL B={1,2,3,4,5,1,3,6,9,4},包括所有数据,不会去除重复。

提示:

在使用多个UNION ALL时最好加括号,因为UNION ALL的优先级比其他操作符(如JOIN、WHERE、GROUP BY等)低。这意味着如果不使用括号,查询语句可能会出现问题,因为Oracle将按照默认的优先级顺序执行操作,而不是按照您想要的顺序执行操作。因此,为了确保查询语句按照您期望的顺序执行,最好需要使用括号来明确指定操作的优先级。

二、交集

INTERSECT是一种用于组合两个或多个SELECT语句结果集的操作符。它用于返回两个或多个查询结果集的交集,即返回同时出现在多个结果集中的行。

语法如下:

SELECT column1, column2, ... FROM table1
INTERSECT
SELECT column1, column2, ... FROM table2;

其中,SELECT语句可以包含WHERE、GROUP BY、HAVING、ORDER BY等子句,但是两个SELECT语句的列数和数据类型必须相同。

以下是一个INTERSECT的实例,假设有两个表A和B,它们的结构如下:

Table A:
ID   Name
1    John
2    Amy
3    Tom

Table B:
ID   Name
2    Amy
3    Tom
4    Jack

现在我们要查询同时存在于表A和表B中的记录,可以使用以下语句:

SELECT ID, Name FROM A
INTERSECT
SELECT ID, Name FROM B;

执行结果为:

ID   Name
2    Amy
3    Tom

可以看到,INTERSECT操作符返回了同时存在于表A和表B中的记录,即ID为2和3的记录。

还是这两个数集:

A={1,2,3,4,5};B={1,3,6,9,4};那么A INTERSECT B={1,3,4}。

注意:

INTERSECT操作符只返回重复的行,如果两个表的结果集中没有重复的行,则返回空结果集。此外,INTERSECT操作符的优先级较低,如果与其他操作符一起使用,应该使用括号明确优先级。

三、差集

MINUS是一个关键字,用于在两个SELECT语句之间执行集合差运算(即从第一个结果集中减去第二个结果集中的所有行)。

语法如下:

SELECT column1, column2, ...
FROM table1
MINUS
SELECT column1, column2, ...
FROM table2;

其中,SELECT语句中的列名和表名可以根据实际需要进行替换,MINUS关键字必须大写。

使用MINUS时,需要注意以下几点:

1. 两个SELECT语句中的列数和数据类型必须相同。

2. MINUS操作符只能用于查询结果集,不能用于表之间的操作。

3. 如果第一个SELECT语句中的结果集包含NULL值,则这些行不会被减去。

4. 如果第二个SELECT语句中的结果集包含重复行,则这些行只会被减去一次。

5. 如果第一个SELECT语句中的结果集为空,则MINUS操作返回空结果集。

6. MINUS操作符也可以用EXCEPT代替,两者的作用相同。

以下是一个使用MINUS的实例:

假设我们有两个表,一个是学生表(student),另一个是成绩表(score)。学生表包含学生ID和姓名,成绩表包含学生ID和分数。我们想要找出所有没有成绩的学生。

可以使用以下SQL语句来实现:

SELECT student_id, student_name
FROM student
MINUS
SELECT student_id, score
FROM score;

该语句将返回学生表中所有没有匹配到成绩表的学生ID和姓名。

需要注意:如果成绩表中存在重复的学生ID,则这些学生只会被减去一次。如果学生表中存在重复的学生ID,则这些学生也只会出现一次在结果集中。如果成绩表中存在NULL值,则这些行不会被减去。

已知两个集合C和D,如下:

C:员工表工资高于2000的员工姓名和工资;

select ename,sal from emp where sal>2000;

运行结果如下: 

D: 员工表工资低于2500的员工姓名和工资

select ename,sal from emp where sal<2500;

 分别求出集合C和D的并集、交集、差集;

①并集

union all:

select ename,sal from emp where sal>2000
UNION all--不去重
select ename,sal from emp where sal<2500;

运行结果如下:

 union:

select ename,sal from emp where sal>2000
UNION --去重
select ename,sal from emp where sal<2500;

运行结果如下: 

②交集

select ename,sal from emp where sal>2000
INTERSECT
select ename,sal from emp where sal<2500;

运行结果如下: 

③差集

select ename,sal from emp where sal>2000
MINUS
select ename,sal from emp where sal<2500;

运行结果如下: 

 对集合C和D互换位置再看下结果

select ename,sal from emp where sal<2500
MINUS
select ename,sal from emp where sal>2000;

运行结果如下:

 突然就发现了一个问题,为什么差集操作符(MINUS)的两个集合互换位置后结果不一样?

解析:

在Oracle中,差集操作是非对称的。也就是说,A MINUS B 的结果并不等于 B MINUS A 的结果。

这是因为差集操作是基于集合的,而集合是没有顺序的。因此,当我们对两个集合执行差集操作时,结果取决于它们的元素。如果元素在两个集合中的位置不同,则两个集合互换位置后结果不一样。

举个例子:

假设集合A包含{1, 2, 3},集合B包含{2, 3, 4},则A MINUS B的结果为{1},B MINUS A的结果为{4}。这是因为A MINUS B表示从集合A中减去集合B中的元素,所以1是A中独有的元素,而4是B中独有的元素;而B MINUS A表示从集合B中减去集合A中的元素,所以4是B中独有的元素,而1是A中独有的元素。

注意:

在使用差集操作时,需要仔细考虑两个集合的元素顺序,以确保得到正确的结果。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

树贤森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值