一、基本概念
差集: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