SQL中MINUS、INTERSECT、UNION、UNION All

来源:互联网 发布:烟台百度seo排名公司 编辑:程序博客网 时间:2024/04/28 08:45
一、基本概念
差集:MINUS
交集:INTERSECT
并集:UNION、UNION All。UNION将重复的元组去掉,UNION ALL则不会。
 
表Store_Information 店面营业表

store_name

Sales

Date

分店1

1500

2013-01-05

分店2

250

2013-01-07

分店1

300

2013-01-08

分店3

700

2013-01-08


表Internet Sales 网络营业表

Date

Sales

2013-01-07

850

2013-01-10

535

2013-01-11

320

2013-01-12

750

应用两个集合的相减,相交和相加时,是有严格要求的:内部的SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。每条SELECT 语句中的列的顺序必须相同

①两个集合的字段必须明确,用*报错
②字段类型和顺序相同,名称可以不同,如集合1的字段1是NUMBER,字段2是VARCHAR,那集合2的字段1必须也是NUMBER,字段2必须是VARCHAR
③不能排序,如果要对结果排序,可以在集合运算后,外面再套一个查询,然后排序。
SELECT * FROM (SELECT order_id FROM made_order MINUS SELECT order_id FROM charge_detail) ORDER BY ORDER_ID 

二、MINUS

SELECT column_name(s) FROM table_name1
MINUS
SELECT column_name(s) FROM table_name2

查找有店面营业额,但没有网络营业额的日期。
SELECT Date FROM Store_Information
MINUS
SELECT Date FROM Internet_Sales
结果:
Date
2013-01-05
2013-01-08
可以这样理解,两个表的Date字段组成了一个[5,7,8,10,11,12]全集,减去网络营业表的Date[7,10,11,12]剩下[5,8]就是需要的结果。

三、UNION、UNION All
查找所有有营业额的日子
SELECT Date FROM Store_Information
UNION
SELECT Date FROM Internet_Sales
Date 
2013-01-05 
2013-01-07 
2013-01-08
2013-01-10 
2013-01-11
2013-01-12

UNION ALL 和 UNION 不同之处在于 UNION ALL 会将每一笔符合条件的数据都列出来,无论资料值有无重复。

SELECT Date FROM Store_Information
UNION ALL
SELECT Date FROM Internet_Sales
Date 
2013-01-05 
2013-01-07 
2013-01-08 
2013-01-08 
2013-01-07 
2013-01-10 
2013-01-11
2013-01-12

四、INTERSECT可以查相关资料

五、性能问题和注意点

虽然同样的功能可以用简单SQL语句来实现,但性能差别非常大。made_order共23万笔记录,charge_detail共17万笔记录:
SELECT order_id FROM made_order
MINUS
SELECT order_id FROM charge_detail
耗时:1.14 sec
  
SELECT a.order_id FROM made_order a
 WHERE a.order_id NOT exists (
 SELECT order_id
 FROM charge_detail
 WHERE order_id = a.order_id
)
耗时:18.19 sec

性能相差15.956倍。因此在遇到这种问题的时候,还是用MINUS,INTERSECT和UNION ALL来解决问题。


原帖地址:
http://www.cnblogs.com/fxgachiever/archive/2010/09/10/1823057.html
http://blog.csdn.net/gan690416372/article/details/5012397
0 0