union是mysql中用于合并多個(gè)select查詢結(jié)果集的操作符,要求各查詢列數(shù)和數(shù)據(jù)類型一致,默認(rèn)自動(dòng)去重,使用union all可保留重復(fù)記錄;其常見場(chǎng)景包括:1.合并結(jié)構(gòu)相似的不同表數(shù)據(jù),如分表存儲(chǔ)的訂單信息;2.統(tǒng)一展示多類別內(nèi)容,如論壇帖子、評(píng)論與回復(fù)的時(shí)間線;3.構(gòu)造虛擬數(shù)據(jù)輔助分析或測(cè)試;使用時(shí)需注意字段數(shù)量順序一致、類型匹配、性能優(yōu)化及排序僅在最后使用。
在mysql中,union 是一個(gè)非常實(shí)用的操作符,用于合并兩個(gè)或多個(gè) select 查詢的結(jié)果集。它不僅能讓查詢結(jié)構(gòu)更清晰,還能幫助我們從不同表中提取相似數(shù)據(jù)并整合輸出。
什么是UNION?
簡(jiǎn)單來說,UNION 可以把多個(gè)結(jié)構(gòu)相似的查詢結(jié)果“拼接”在一起,形成一個(gè)統(tǒng)一的結(jié)果集。但需要注意的是,每個(gè) SELECT 語句中的列數(shù)和數(shù)據(jù)類型必須一致(或者兼容),否則會(huì)報(bào)錯(cuò)。
UNION的基本用法
基本語法如下:
SELECT column1, column2 FROM table1 UNION SELECT column1, column2 FROM table2;
默認(rèn)情況下,UNION 會(huì)自動(dòng)去重,只保留唯一值。如果你希望保留重復(fù)記錄,可以使用 UNION ALL。
比如你有兩個(gè)用戶表:users_vip 和 users_regular,它們都有 id 和 name 字段,想查出所有用戶的姓名,就可以這樣寫:
SELECT name FROM users_vip UNION SELECT name FROM users_regular;
這樣就能得到一個(gè)不重復(fù)的用戶名單了。
使用UNION的常見場(chǎng)景
場(chǎng)景一:合并來自不同表的數(shù)據(jù)
當(dāng)你的數(shù)據(jù)分散在多個(gè)結(jié)構(gòu)相同或類似的表中時(shí),可以用 UNION 來統(tǒng)一查詢。例如訂單系統(tǒng)中,可能有按月份分表的歷史訂單數(shù)據(jù),如 orders_202401, orders_202402 等,這時(shí)可以通過 UNION 把這些表合并查詢。
SELECT order_id, amount FROM orders_202401 UNION ALL SELECT order_id, amount FROM orders_202402;
注意:這種情況下一般使用 UNION ALL,因?yàn)槊總€(gè)子表之間不會(huì)有重復(fù)數(shù)據(jù),不需要去重,效率更高。
場(chǎng)景二:統(tǒng)一展示多類別的信息
假設(shè)你有一個(gè)論壇系統(tǒng),里面有帖子、評(píng)論、回復(fù)三種內(nèi)容類型,分別存在不同的表里,但都包含 content 和 created_at 字段。你可以通過 UNION 把這三類內(nèi)容合并展示為一個(gè)時(shí)間線:
SELECT content, created_at FROM posts UNION SELECT comment_text AS content, created_at FROM comments UNION SELECT reply_text AS content, created_at FROM replies ORDER BY created_at DESC;
這樣就得到了一個(gè)混合的時(shí)間線展示。
場(chǎng)景三:構(gòu)造虛擬數(shù)據(jù)輔助分析
有時(shí)候?yàn)榱俗鼋y(tǒng)計(jì)或測(cè)試,需要手動(dòng)構(gòu)造一些數(shù)據(jù),也可以結(jié)合 UNION 實(shí)現(xiàn):
SELECT '北京' AS city, 2154 AS population UNION SELECT '上海', 2415 UNION SELECT '廣州', 1490;
這樣可以直接生成一個(gè)城市人口的小數(shù)據(jù)集,方便后續(xù)處理。
使用UNION時(shí)需要注意的地方
-
字段數(shù)量和順序要一致
每個(gè) SELECT 的字段數(shù)量必須相同,且順序最好一致,否則可能會(huì)出現(xiàn)數(shù)據(jù)錯(cuò)位。 -
字段類型盡量匹配
雖然MySQL允許一定程度上的隱式轉(zhuǎn)換,但為了準(zhǔn)確性,建議字段類型保持一致或兼容。 -
性能問題
UNION 默認(rèn)去重,如果數(shù)據(jù)量很大,會(huì)影響性能。這時(shí)候如果確認(rèn)沒有重復(fù),或者不關(guān)心是否重復(fù),應(yīng)優(yōu)先使用 UNION ALL。 -
排序放在最后
如果你要對(duì)整個(gè)結(jié)果集排序,ORDER BY 只能出現(xiàn)在最后一個(gè) SELECT 后面。
小結(jié)
總的來說,UNION 在需要合并多個(gè)查詢結(jié)果的時(shí)候非常好用,特別是在數(shù)據(jù)來源多樣但結(jié)構(gòu)相似的情況下。只要注意字段匹配、性能優(yōu)化和合理使用 UNION ALL,就能寫出既簡(jiǎn)潔又高效的sql語句。
基本上就這些,用得多了自然就熟練了。