MySQL必知必會:組合查詢(Union)
本篇文章主要介紹使用Union
操作符將多個SELECT
查詢組合成一個結果集。本文參考《Mysql
必知必會》+工作實踐融合
組合查詢
定義
在大多數開發中,使用一條SELECT
查詢就會返回一個結果集。如果,我們想一次性查詢多條SQL語句,並將每一條SELECT
查詢的結果合併成一個結果集返回。就需要用到Union
操作符,將多個SELECT
語句組合起來,這種查詢被稱為並(Union
)或者複合查詢。
組合查詢適用於下面兩種情境中:
從多個表中查詢出相似結構的資料,並且返回一個結果集
從單個表中多次
SELECT
查詢,將結果合併成一個結果集返回。
演示
我們通過一個簡單的示例來認識一下Union
組合查詢。
建立一個使用者表
首先分兩次查詢使用者表,然後再組合查詢
select user_id,user_nickname,user_status from yy_user where user_status = 1 // 第一次查詢
select user_id,user_nickname,user_status from yy_user where user_id > 3 // 第二次查詢
第一條SQL
查詢了user_status=1
的使用者,第二條查詢了user_id > 3
的使用者
下面我們組合這兩條SQL
語句:
select user_id,user_nickname,user_status from yy_user where user_status = 1
UNION
select user_id,user_nickname,user_status from yy_user where user_id > 3
這條語句由前面的兩條語句組成,通過Union
組合了兩條SELECT
,並且把結果集合並後輸出。這條組合查詢也可以使用同等where
語句來替代:
select user_id,user_nickname,user_status from yy_user where user_status = 1 or user_id > 3;
組合查詢和Where
where
和Union
在多數情況下都可以實現相同的結果集。where
Union
語句來實現。但是反過來就不一定正確了,比如下面將會說到的去重和不去重。另外,在單表中使用Union
比where
多條件查詢較為複雜。而從多張表中獲取資料,使用Union
會相對於簡單些。
Union使用規則
Union
有他的強大之處,詳細介紹之前,首先明確一下Union
的使用注意規則。
Union
必須由兩條或者兩條以上的SELECT
語句組成,語句之間使用Union
連結。Union
中的每個查詢必須包含相同的列、表示式或者聚合函式,他們出現的順序可以不一致(這裡指查詢欄位相同,表不一定一樣)列的資料型別必須相容,相容的含義是必須是資料庫可以隱含的轉換他們的型別
包含重複、去除重複
我們觀察一下上面兩條語句,第一條SELECT
返回了2條資料;第二條SELECT
也返回了2條資料。
但是Union
最終的結果返回了3條資料,而不是4條。mysql
在查詢結果集中幫我們自動去除了重複的行(重複的行是李四),把兩條李四合並了。
一般情況下這樣結果是好的,但是如果需要的情況下,我們可以使用Union All
操作符來取消自動合併功能。
select user_id,user_nickname,user_status from yy_user where user_status = 1
UNION ALL
select user_id,user_nickname,user_status from yy_user where user_id > 3
這一次mysql
沒有幫我們去除重複,在查詢結果中,我們也看到了兩條重複的李四。
之前我們說過where
和Union
的區別,這裡Union All
可以返回重複的資料,就是where
子句完成不了的工作。
結果排序
使用Union
組合查詢時,只能使用一條order by
子句對結果集進行排序,而且必須出現在最後一條出現的SELECT
語句之後。因為`Union
不允許對於部分結果集進行排序,只能針對最終檢索出來的結果集進行排序。
注意:由於在多表組合查詢時候,可能表字段並不相同。所以,在對於結果集排序的時候需要使用檢索出來的共同欄位。
(select user_id,user_nickname,user_status from yy_user where user_status = 1)
UNION ALL
(select user_id,user_nickname,user_status from yy_user where user_id > 3)
order by user_id desc
上面檢索的欄位user_id
必須存在於結果集中。
多表組合查詢
大型專案中資料經常分佈在不同的表,檢索的時候需要組合查詢出來。多表查詢的時候,並不要求兩個表完全相同,只需要你檢索的欄位結構相似就可以。
我們已經有一張user
表,假設搜尋時候我們需要將使用者暱稱和部落格文章標題一同混合檢索。
看下上面的posts
表,posts_name
和user_nickname
型別相同,而posts_id
和user_id
型別相同,post_status
和user_status
型別相同。儘管他們的名稱不相同。
我們可以這麼來檢索:
select posts_id,posts_name,posts_status from yy_posts
UNION
select user_id,user_nickname,user_status from yy_user
從上面的檢索結果能看出,我們將兩個表的資料組合了起來。Union
檢索遇到不一致的欄位名稱時候,會使用第一條SELECT
的查詢欄位名稱,或者你使用別名來改變查詢欄位名稱。
區分多表
上一個例子中,我們組合查詢了user
表和posts
表。雖然結果混合在一起沒有任何問題,但是當顯示到頁面的時候,我們需要給使用者和文章不同的連結或者其他的區分。所以我們必須確定該條記錄來自於哪張表,我們可以新增一個別名來作為表名。
select posts_id,posts_name,posts_status,'users' as table_name from yy_posts
UNION
select user_id,user_nickname,user_status,'posts' as table_name from yy_user
注意SQL
語句中的'users' as table_name
。對應的是圖片裡的table_name
,就是我們剛剛新增用於區別表的欄位。