首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MySql 使用 UNION 把多个不同表的查询结果整合到一起

在做数据统计的时候,经常遇到奇葩需求,把多个不同表的查询结果放在一个列表里展示。

第一次遇到这样的需求还是在十几年前,当时还是个没有开发经验的小白。接到这个需求的第一个反应是,这怎么可能完成呢。

于是找 Leader,一个同龄人。虽是同龄人,但是人家已经有数年的开发经验。只见她用笔在草稿纸上画画,用了2个关键字就把我征服了。

这两个关键字就是UNION 和 UNION ALL。

一、UNION 和 UNION ALL

在 MySQL 中,我们可以使用 UNION 操作符将多个不同表的查询结果整合在一起。UNION 操作符用于合并两个或多个 SELECT 语句的结果集。每个 SELECT 语句的列数必须相同,并且列的数据类型必须兼容。

举个例子:

假设你有两个表 table1 和 table2,它们的结构如下:

CREATE TABLE table1 ( id INT, name VARCHAR(50));

CREATE TABLE table2 ( id INT, city VARCHAR(50));

我们可以使用如下的 SQL 语句将它们的查询结果合并在一起:

SELECT id, name FROM table1UNIONSELECT id, city FROM table2;

这个查询会将 table1 中的 id 和 name 列与 table2 中的 id 和 city 列整合在一起,并返回一个包含所有结果的结果集。

如果想要包括重复的行,可以使用 UNION ALL,而不是 UNION。

我们还可以把 UNION 后的语句封装成一个单独的表,然后再对这个表进行join 或者条件查询:

select A.* from (SELECT id, name FROM table1UNIONSELECT id, city FROM table2) as Aleft join ... on...where A.id = ...

二、不存在的字段可以无中生有

两个不同的表,在表设计上不一定全部一样。如果一个表中的字段,另一个表中没有,这两个表怎么合并呢?

很好办,无中生有。它没有我们就给它造一个。

比如,在 table1 中有一个字段 name,table2中就没有。table2中有city,但table1中就没有。

select A.* from (SELECT id, name,null as city FROM table1UNIONSELECT id, "" as name, city FROM table2) as A

在 table1 中,设置一个默认值null,并且给这个值起个别名为city。在table2中,设置一个默认值空字符串,并且起个别名为name。这样两个表的字段就对应起来可以合并了。

需要注意的是:不同表的字段要一一对应。在 UNION 联合子句里,它不会帮你把字段对应起来。因此我们在写查询语句的时候,就需要把字段一一对应起来,每个表的字段和第一个的字段看齐,否则容易数据错乱。

比如说,这个查询语句,查出来的字段向第一个表看齐,字段顺序为:id,name,city,age。第二个表的字段顺序错了,name和city字段位置颠倒了,它也不会帮你订正。

select A.* from (SELECT id, name, city, age FROM table1UNIONSELECT id, city, name, null as age FROM table2) as A

因此,UNION 多个表时,一定要把每个表的字段顺序排放好。

三、IF应用

统计数据 IF 少不了。

IF 是 MySQL 中的条件函数,用于在查询中根据条件返回不同的值。它的基本语法如下:

IF(condition, value_if_true, value_if_false)

condition 是一个条件表达式,如果条件为真,则返回 value_if_true,否则返回 value_if_false。

value_if_true 是在条件为真时要返回的值。

value_if_false 是在条件为假时要返回的值。

我们可以使用 IF 函数根据某个条件返回不同的结果:

SELECT IF(score >= 60, 'Pass', 'Fail') AS result FROM students;

上面的查询将返回学生是否及格的结果,如果分数大于等于 60,则返回 'Pass',否则返回 'Fail'。

如果是等于要这么写:

SELECT IF(score= 60, 'Pass', 'Fail') AS result FROM students;

等于无需写双等号。

四、用UNION替代LEFT JOIN

在写一个复杂查询语句的时候,我用了 LEFT JOIN,一个主表 LEFT JOIN 4个子表,查询条件里还有个 IN,IN 的是 UID,最多放10个 UID,目前有3个 UID,每个 UID 36位字符串,千把条的数据几百秒还没查完,实在受不了,就把查询中止了。

怎么办?拆!

把4个子表拆分成4个查询语句,然后用 UNION ALL 连接,最后再进行数据汇总。查询时间立马将为零点几秒。

在做这个统计的时候,我也提出统计的不合理处,但是上头就是要这样做,还觉得高效,没办法,拿人钱财替人做事,那就做吧。

这条仅作参考,毕竟没有相同的业务逻辑。如果遇到 JOIN 表很多,查询数据又非常慢,不妨使用 UNION 替换试试,说不定就解决了性能问题。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OcI7HlKR0bus1BKfR0Udd_eA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券