1.背景:連接查詢無法滿足需求
我們都知道連接查詢有內連接和外連接,那幾種集合圖看過不少,
-
INNER JOIN(內連接,或等值連接):獲取兩個表中字段匹配關係的記錄。
-
LEFT JOIN(左連接):獲取左表所有記錄,即使右表沒有對應匹配的記錄。
-
RIGHT JOIN(右連接): 與 LEFT JOIN 相反,用於獲取右表所有記錄,即使左表沒有對應匹配的記錄。
但是最近遇到一種場景使用連接查詢怎樣都不能滿足需求。具體如下
A表:
id |
content |
---|---|
1 |
aaa |
2 |
bbb |
3 |
ccc |
B表:foreign_id連接A表的id
id |
name |
foreign_id |
---|---|---|
1 |
xiaoming1 |
2 |
2 |
xiaoming2 |
3 |
3 |
xiaoming3 |
1 |
C表:foreign_id連接A表的id
id |
name |
foreign_id |
---|---|---|
1 |
xiaoming1 |
3 |
2 |
xiaoming2 |
2 |
3 |
xiaoming3 |
2 |
現在需要查詢xiaoming1對應的A表的記錄,
需要的查詢結果:
id |
content |
---|---|
2 |
bbb |
3 |
ccc |
使用連接能想到的寫法,B.*和C.*是爲了便於分析
select
A.*,B*,C*
from A
left join B on B.foreign_id = A.id
left join C on C.foreign_id = A.id
where B.name = 'xiaoming1' or C.name = 'xiaoming1';
查詢結果:
id |
content |
id |
name |
foreign_id |
id |
name |
foreign_id |
---|---|---|---|---|---|---|---|
2 |
bbb |
1 |
xiaoming1 |
2 |
2 |
xiaoming2 |
2 |
2 |
bbb |
1 |
xiaoming1 |
2 |
3 |
xiaoming3 |
2 |
3 |
ccc |
2 |
xiaoming2 |
3 |
1 |
xiaoming1 |
3 |
這樣得到的結果A表結果有一條重複的(如紅色),不論是內連接還是右外連接,均無法滿足需求
2.聯合查詢 union
聯合查詢比較容易理解,即將多個查詢語句的結果集合在一起顯示
語法:select column_name(s) from table_name1 UNION select column_name(s) from table_name2
上面的需求SQL語句可以這樣寫
select
A.*
from A
left join B on B.foreign_id = A.id
where B.name = 'xiaoming1'
UNION
select
A.*
from A
left join C on C.foreign_id = A.id
where C.name = 'xiaoming1'
注意:1.兩個查詢結果字段數量必須相同 2.重複的數據的會合併爲一條(如果不想合併可以用union all)
使用上,如果需要對合並後的結果集 order by 、limit 、count,需要這樣寫,將合併後結果集當作子查詢
select userid from
(select userid from testa
union
select userid from testb) t
order by userid limit 0,1;