天天看點

ARTS Share9 Oracle中的Union、Union All、Intersect、Minus

這篇文章說一個關于

ORACLE

中的

UNION

UNION ALL

INTERSECT

MINUS

的解釋和用法:

先建立一張

TABLE

,用來做實驗:

建表語句如下所示:

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

insert into student values(1,'zhangsan',78);
insert into student values(2,'lisi',76);
insert into student values(3,'wangwu',89);
insert into student values(4,'zhaoliu',90);
insert into student values(5,'xiaohua',73);
insert into student values(6,'xiaoming',61);
insert into student values(7,'xiaoli',99);
insert into student values(8,'wangmazi',56);
insert into student values(9,'huqingniu',93);
insert into student values(10,'zhangwuji',90);

commit;
           

檢視插入表中的所有資料:

SELECT * FROM STUDENT;
           

結果如下圖所示:

ARTS Share9 Oracle中的Union、Union All、Intersect、Minus

(1)使用

UNION

對兩個結果集進行連接配接,

SQL

如下所示,結果如下圖所示

SELECT * FROM STUDENT T
WHERE T.ID<4
UNION 
SELECT * FROM STUDENT T
WHERE T.ID>2 AND T.ID<6;
           
ARTS Share9 Oracle中的Union、Union All、Intersect、Minus

通過上圖我們可以看出來,使用

UNION

傳回了5條資料。

(2)使用

UNION ALL

對兩個結果集連接配接,

SQL

如下所示,結果如下圖所示:

SELECT * FROM STUDENT T
WHERE T.ID<4
UNION ALL
SELECT * FROM STUDENT T
WHERE T.ID>2 AND T.ID<6;
           
ARTS Share9 Oracle中的Union、Union All、Intersect、Minus

通過上圖我們可以看出來,使用

UNION ALL

傳回了6條資料,與(1)中的結果相比,多了一條

ID

為3的資料。

為什麼會這樣,我們看一下我們的

SQL

,我們的語句是由兩部分查詢結果集進行組合的,是以分别單獨看一下每一部分的

SQL

第一部分:

SELECT * FROM STUDENT T WHERE T.ID<4

這句

SQL

會傳回

ID

小于4的記錄,單獨執行應該傳回3條資料,

ID

為1,2,3的記錄

第二部分:

SELECT * FROM STUDENT T WHERE T.ID>2 AND T.ID<6

這句

SQL

會傳回

ID

大于2小于6的記錄,也就是3條記錄,

ID

為3,4,5的記錄

當我們使用

UNION

的時候,傳回的記錄

ID

分别為1,2,3,4,5,并不是上面分析的兩部分直接組合,而是将兩部分中相同的記錄進行了去重,隻留下重複記錄中的一條資料。

當我們使用

UNION ALL

的時候,傳回的記錄

ID

分别是1,2,3,3,4,5,是兩部分的記錄集直接組合,并沒有對重複的記錄進行去重。

是以通過上面這個例子,我們可以知道:

UNION

會對記錄集中重複記錄去重,

UNION ALL

不會對記錄集中的重複記錄去重,是以在寫

SQL

文的時候,需要考慮到底是需要去重還是不去重,去重選擇前者,不去重選擇後者,當然如果選擇前者的話,那麼

SQL

性能會低于後者,因為後者隻是對記錄的展示,而前者需要對查詢的記錄集中的重複記錄進行去重,多了一個步驟,是以會影響

SQL

的性能。

(3)對于(1)和(2)中的

SQL

連接配接順序調整一下,原來是先篩選

ID

小于4的記錄集連接配接篩選

ID

大于2小于6的記錄集,現在我們颠倒一下,

SQL

如下圖所示:

SELECT * FROM STUDENT T
WHERE T.ID>2 AND T.ID<6
UNION 
SELECT * FROM STUDENT T
WHERE T.ID<4;
           

結果如圖所示:

ARTS Share9 Oracle中的Union、Union All、Intersect、Minus
SELECT * FROM STUDENT T
WHERE T.ID>2 AND T.ID<6
UNION ALL
SELECT * FROM STUDENT T
WHERE T.ID<4;
           

結果如圖所示:

ARTS Share9 Oracle中的Union、Union All、Intersect、Minus

通過(3)中的第一段

SQL

和結果圖檔,可以看到傳回了5條記錄,但是細心點可以發現它傳回的記錄進行了排序,因為我們

SQL

寫的是先篩選

ID

大于2小于6的,但是結果卻和我們預想的不一樣;第2段

SQL

,傳回了6條記錄,按照我們預想的一樣,記錄集的

ID

是3,4,5,1,2,3,

SQL

是怎麼寫的,結果集就按照其進行輸出。

通過(3),我們應該可以發現,

UNION

會對記錄集進行排序,

UNION ALL

不會對記錄集進行排序。

(4)從(3)中知道了使用

UNION

的話,會對結果集進行排序,我們從(3)中第一段

SQL

結果集發現是按照

ID

進行升序排序的,那麼為什麼會按照

ID

進行排序,我們試圖修改一下

SQL

,再看是否還是按照

ID

排序:

修改後的

SQL

文:

SELECT T.SCORE,T.ID,T.NAME FROM STUDENT T
WHERE T.ID>2 AND T.ID<6
UNION 
SELECT T.SCORE,T.ID,T.NAME FROM STUDENT T
WHERE T.ID<4;
           

對應的記錄集如下圖所示:

ARTS Share9 Oracle中的Union、Union All、Intersect、Minus

通過這個記錄集,可以發現,這個查詢記錄是按照

SCORE

進行排序的,那麼我們就可以認為,

UNION

的排序,是按照查詢列的字段名字順序排序的,比如

SELECT COLUMN1,COLUMN2,COLUMN3 FROM TABLENAME T 
UNION
SELECT COLUMN1,COLUMN2,COLUMN3 FROM TABLENAME T  
           

結果集就是按照

ORDER BY COLUMN1,COLUMN2,COLUMN3

進行排序的。

為了驗證上面我們的說話,

UNION

會按照查詢的列的字段名字升序排序,下面再看一個例子:

SELECT SCORE, ID, NAME
  FROM STUDENT
 WHERE ID > 2
UNION
SELECT SCORE, ID, NAME
  FROM STUDENT
 WHERE ID < 4
           

結果如圖所示:

ARTS Share9 Oracle中的Union、Union All、Intersect、Minus

通過上圖可以看出,的确是按照查詢字段進行排序,當第一個排序字段值相同的時候,按照第二個字段的值進行排序,以此類推。

如果我們需要讓查詢記錄集按照我們的要求進行排序,那麼就需要在整段

SQL

的末尾寫上

ORDER BY COLUMNS

,這樣的話,記錄集就是按照我們的要求進行排序的,測試如下:

SELECT SCORE, ID, NAME
  FROM STUDENT
 WHERE ID > 2
UNION
SELECT SCORE, ID, NAME
  FROM STUDENT
 WHERE ID < 4
 ORDER BY ID DESC
           

運作結果如圖所示:

ARTS Share9 Oracle中的Union、Union All、Intersect、Minus

總結:

  1. UNION

    會對記錄集中的重複記錄進行去重,并且會按照查詢的字段列進行預設升序排序
  2. UNION ALL

    不會對記錄集中的重複記錄進行去重,隻會将查詢記錄組合顯示出來,也不會進行排序
  3. 使用

    UNION

    的記錄集需要排序,可以在

    SQL

    的最末端,寫

    ORDER BY COLUMNS

    ,你需要排序的字段名稱
  4. Intersect

    對兩個結果集進行交集操作,不包括重複行,同時進行預設規則的排序
  5. Minus

    對兩個結果集進行差操作,不包括重複行,同時進行預設規則的排序
ARTS Share9 Oracle中的Union、Union All、Intersect、Minus