勿以惡小而爲之,勿以善小而不爲--------------------------劉備
上一章簡單介紹了 MySQL的子查詢(二十),如果沒有看過,請觀看上一章
一. 合併查詢結果
多條sql 查詢語句的合併處理,有兩種不同的形式,
第一種是子查詢, 一些sql查詢語句的輸出是另一條sql查詢語句的輸入,
第二種是 合併查詢結果, 將多條查詢結果結構相同的數據進行合併運算。
第一次查詢出來的是一個二維表,第二次查詢出來的也是一個二維表, 那麼就可以將這兩次的查詢結果進行合併,
合併包括取並集, 取交集, 取差集。
但是 MySQL數據庫只支持 並集(union 和union all),不支持交集(intersect) 和差集(minus)。
要想對前後不同的查詢語句的結果進行合併,必須要保證 前後的查詢結果的結構是一樣的。(查詢的列名總數一致,與列名結構的排列順序無關,與查詢出來的結果行數量無關)
查詢語句1:
語句1: select * from user ;
語句 2: select id,name from user;
猜想1:
語句1 會將user 表中的所有的列都查詢出來,包括id,name,sex,birthday,age,description ,
語句2 只會查詢出 id,name 的兩行列
列的總數是不一致的,結構不同,所以這兩次的查詢結果是不能合併的。
查詢語句2:
語句 3: select * from user;
語句 4: select * from user where id=1;
猜想2:
語句 3會查詢出所有的列, 多條記錄
語句4 會查詢出所有的列, 一條記錄
列的總數一致,排列順序也一致,所以結構是相同的,可以進行合併。
查詢語句3:
語句 5: select id,name,age from user;
語句 6: select id,name,age from user where id=1;
猜想3:
語句 5只會查詢出 id 和name,age 三個列, 多條記錄
語句 6 會查詢出id,name 三個列,但只有一條記錄
列的總數一致,都是三列,順序也一致,結構相同,所以是可以合併的。
查詢語句4:
語句 7: select id,name,age from user;
語句 8: select name,id,age from user where id=1;
猜想4:
語句 7 只會查詢出 id,name,age 三個列,多條記錄,類型依次是 int,varchar,int
語句 8 只會查詢出 name,id,age 三個列,單條記錄, 類型依次是 varchar,int,int
列的總數一致,都是三列,雖然前後的類型不一致,但依然是可以合併的。
二. 並集 union 和 union all (重要)
union 和 union all 是求並集的, 將前後的查詢結果進行合併。
其中,union 是先去重,後合併,不保留重複的數據, union all 是直接合並,會保留重複的數據。 兩者是有一些區別的。
如 查詢 id>=3 和 id<=4 的數據。
查詢 id>=3的結果:
select * from user where id>=3;
查詢 id<=4的結果:
select * from user where id<=4;
兩次查詢結果中, 有相同的數據, 那就是 id=3和 id=4的數據。
二.一 union 先去重,後合併
select * from user where id>=3
union
select * from user where id<=4;
查詢順序 是先展示 id>=3 的數據,再展示 id<=4 的順序, 如果 有重複的,則先去重。
union 最後查詢出來的結果,沒有重複的數據。
二.二 union all 直接合並
select * from user where id>=3
union all
select * from user where id<=4;
union all 並不會去掉重複的數據, 而是直接拼接後展示。
問題1: 如果前後查詢列不一致,會報什麼錯誤呢?
select id,name,age from user where id>=3
union
select * from user where id<=4;
ERROR 1222 (21000): The used SELECT statements have a different number of columns
問題2: 前後類型不一致,能合併嗎?
select id,name,age from user where id>=3
union
select name,id,age from user where id<=4;
可以進行合併,只是 合併後的數據有些問題。
三 交集
查詢交集,可以利用子查詢和連接查詢進行處理。 from 語句的子查詢和 內連接
如 還是查詢 id>=3 和 id<=4 的數據, 它們的交集是 id=3 和id =4
交集,一定是 a 裏面有的。
select t1.* from (
select * from user where id>=3
) t1
inner join (select * from user where id<=4) t2
on t1.id=t2.id and t1.name=t2.name ;
其中 on 條件,是唯一標識, 這裏用 id 和 name 兩個標識, 實際開發中,只用一個 id 即可。
四 差集
查詢差集, 也可以利用子查詢和連接查詢進行處理。 from 語句的子查詢 和左外連接
查詢 id>=3 和 id<=4 的數據,
如果是 id>=3 減去 id<=4 的, 那麼查詢出來的數據 就應該是 id>=5 的數據了。
查詢出來的數據,一定在 id>=3 裏面。
select t1.* from (
select * from user where id>=3
) t1
left join (select * from user where id<=4) t2
on t1.id=t2.id and t1.name=t2.name
where t2.id is null;
如果 是 id<=4 減去 id>=3 , 那麼查詢出來的數據就應該是 id<=2 的數據了。
查詢出來的數據,一定在 id<=4 裏面。 這個時候,就應該用右連接了。
select t2.* from (
select * from user where id>=3
) t1
right join (select * from user where id<=4) t2
on t1.id=t2.id and t1.name=t2.name
where t1.id is null;
謝謝!!!