zoukankan      html  css  js  c++  java
  • Oracle中的Union、Union All、Intersect、Minus

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

    假设我们有一个表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 

    看看执行结果是否和你期望的一致?  

    --Union All  

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

    union all  

    select * from student where id < 4  那么这个呢? 
    据此我们可知,区别之二在于对排序的处理。

    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、Union All、Intersect、Minus都有效。 

    注意:
    1,Union可以对字段名不同但数据类型相同的结果集进行合并;
    2,如果字段名不同的结果集进行Union,那么对此字段的Order by子句将失效。
    =================================================================================================================
    Intersect和Minus的操作和Union基本一致,这里一起总结一下:
    Union,对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序; 
    Union All,对两个结果集进行并集操作,包括重复行,不进行排序;
    Intersect,对两个结果集进行交集操作,不包括重复行,同时进行默认规则的排序; 
    Minus,对两个结果集进行差操作,不包括重复行,同时进行默认规则的排序。 
    可以在最后一个结果集中指定Order by子句改变排序方式。
     
    Oracle Minus
    //创建表1
    create table test1 (
     name varchar(10),  sex varchar(10),  age int );
    insert into test1 values('luxin','female',25); 

    insert into test1 values('tom','female',26); 

    insert into test1 values('mary1','male',27); 

    insert into test1 values('money','male',27); 

    insert into test1 values('tony','male',28); 

    insert into test1 values('tony1','male',19);  
    //创建表2
    create table test2 ( name varchar(10),  sex varchar(10),  age int );  
    insert into test2 values('luxin','female',25); 

    insert into test2 values('tom','female',26); 

    insert into test2 values('mary2','male',27); 

    insert into test2 values('money','male',27); 

    insert into test2 values('tony','male',28); 

    insert into test2 values('tony2','male',19);  
    ------------------------------------------- 

    select * from test1 minus select * from test2; 

    结果:
    NAME       SEX               AGE

     ---------- ---------- ---------- 

    mary1      male               27 

    tony1      male               19  
    ----------------------------------------------------------- 

    select * from test2 minus select * from test1; 

    结果:
    NAME       SEX               AGE 

    ---------- ---------- ---------- 

    mary2      male               27 

    tony2      male               19  
    结论:Minus返回的总是左边表中的数据,它返回的是差集。 用表1-表2中的数据,如果相同,则去掉,否则返回表1中的数据。  
    ========================================================== 

    今天在看数据集合时偶然看到了SQL 有MINUS,可以达到相同的目的   具体如下:
      SQL中的MINUS关键字
    SQL中有一个MINUS关键字,它运用在两个SQL语句上,它先找出第一条SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果中。如果有的话,那这一笔记录就被去除,而不会在最后的结果中出现。如果第二个SQL语句所产生的结果并没有存在于第一个SQL语句所产生的结果内,那这笔资料就被抛弃,其语法如下:   
    [SQL Segment 1]   
    MINUS
    [SQL Segment 2]
      其实简单的一句话就是找出第一条SQL查询的不在第二条SQL语句查询结果中的那些记录,并且要注意最后返回的结果集中,不同的记录只会被列出一次!   下面是我做的实验,很明显能够看出MINUS的效率,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 NOT exists (    SELECT 1
    FROM charge_detail  WHERE order_id = a.order_id    )
    18.19 sec   
    SELECT order_id FROM made_order   WHERE order_id NOT in (    SELECT order_id    FROM charge_detail    )
    20.05 sec   
    还有其它一下关键字:   
    INTERSECT (交集)   
    UNION ALL 并集
     






  • 相关阅读:
    XML(学习笔记)
    css样式学习笔记
    Request(对象)
    sql一些错误修改的总结
    转载(如何学习C#)
    sql server(学习笔记2 W3Cschool)
    sql sqrver(学习笔记1 W3Cschool)
    关于 flutter开发碰到的各种问题,有的已经解决有的一直没解决或者用其他方法替代
    关于 Flutter IOS build It appears that your application still contains the default signing identifier.
    关于 flutter本地化问题 The getter 'pasteButtonLabel' was called on null
  • 原文地址:https://www.cnblogs.com/edwardsun/p/3483853.html
Copyright © 2011-2022 走看看