Union语句

UNION 指令的目的是将两个 SQL 语句的结果合并起来。从这个角度来看, UNION 跟 JOIN 有些许类似,

因为这两个指令都可以由多个表格中提取资料。 UNION 的一个限制是两个SQL查询出来的结果必须具有相

同的列数、对应列的类型必须一样,这样才可以做union操作

在数据库中,UNION和UNION ALL关键字都是将两个结果集合并为一个,但这两者从使用和效率上来说都有

所不同。

UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复

的记录再返回结果。

假设我们有以下的两个表格,
Store_Information 表格
Sql代码
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999

Internet Sales 表格
Sql代码
Date Sales
Jan-07-1999 $250
Jan-10-1999 $535
Jan-11-1999 $320
Jan-12-1999 $750


而我们要找出来所有有营业额 (sales) 的日子。要达到这个目的,我们用以下的 SQL 语句: Sql代码
SELECT Date FROM Store_Information
UNION
SELECT Date FROM Internet_Sales


这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表

数据量大的话可能会导致用磁盘进行排序。

而UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返

回的结果集就会包含重复的数据了。

从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的

话,那么就使用UNION ALL,


众所周知的几个结果集集合操作命令,今天详细地测试了一下,发现一些问题,记录备考。

假设我们有一个表Student,包括以下字段与数据:

drop table student;

create table student
(
id int primary key,
name nvarchar2(50) not null,
score number not null
);

insert into student values(1,'Aaron',78);
insert into student values(2,'Bill',76);
insert into student values(3,'Cindy',89);
insert into student values(4,'Damon',90);
insert into student values(5,'Ella',73);
insert into student values(6,'Frado',61);
insert into student values(7,'Gill',99);
insert into student values(8,'Hellen',56);
insert into student values(9,'Ivan',93);
insert into student values(10,'Jay',90);

commit;

Union和Union All的区别。
select *
from student
where id < 4

union

select *
from student
where id > 2 and id < 6

结果将是

1 Aaron 78
2 Bill 76
3 Cindy 89
4 Damon 90
5 Ella 73

如果换成Union All连接两个结果集,则返回结果是:

1 Aaron 78
2 Bill 76
3 Cindy 89
3 Cindy 89
4 Damon 90
5 Ella 73


可以看到,Union和Union All的区别之一在于对重复结果的处理。

接下来我们将两个子查询的顺序调整一下,改为

--Union

select *
from student
where id > 2 and id < 6

union

select *
from student
where id < 4
结果:
1 Aaron 78
2 Bill 76
3 Cindy 89
4 Damon 90
5 Ella 73




--Union All

select *
from student
where id > 2 and id < 6

union all

select *
from student
where id < 4

结果为:
3 Cindy 89
4 Damon 90
5 Ella 73
1 Aaron 78
2 Bill 76
3 Cindy 89

据此我们可知,区别之二在于对排序的处理。Union All将按照关联的次序组织数据,而Union会根据一定

规则进行排序。那么这个规则是什么?我们换个查询方式看看:

select score,id,name
from student
where id > 2 and id < 6

union

select score,id,name
from student
where id < 4

结果如下:

73 5 Ella
76 2 Bill
78 1 Aaron
89 3 Cindy
90 4 Damon

和我们预料的一致:将会按照字段出现的顺序进行排序。之前我们的查询是基于id,name,score的字段顺序

,那么结果集将按照id优先进行排序;而现在新的字段顺序也改变了查询结果的排序。并且,是按照给定

字段a,b,c...的顺序进行的order by。即结果是order by a,b,c...........的。我们看下一个查询:

select score,id,name
from student
where id > 2

union

select score,id,name
from student
where id < 4

结果如下:

56 8 Hellen
61 6 Frado
73 5 Ella
76 2 Bill
78 1 Aaron
89 3 Cindy
90 4 Damon
90 10 Jay
93 9 Ivan
99 7 Gill

可以看到,对于score相同的记录,将按照下一个字段id进行排序。如果我们想自行控制排序,是不是用

order by指定就可以了呢?答案是肯定的,不过在写法上有需要注意的地方:

select score,id,name
from student
where id > 2 and id < 7

union

select score,id,name
from student
where id < 4

union

select score,id,name
from student
where id > 8
order by id desc

order by子句必须写在最后一个结果集里,并且其排序规则将改变操作后的排序结果(使用union后的结果

使用order by时,select子句中必须明确指出哪些字段,不然的话会出错)。对于Union、Union All、

Intersect、Minus都有效。

注意:

1,Union可以对字段名不同但数据类型相同的结果集进行合并;

2,如果字段名不同的结果集进行Union,那么对此字段的Order by子句将失效。

============================================================================

Intersect和Minus的操作和Union基本一致,这里一起总结一下:

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

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

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

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

可以在最后一个结果集中指定Order by子句改变排序方式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值