mysql的union和union all

Posted 如来神掌十八式

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql的union和union all相关的知识,希望对你有一定的参考价值。

1. sql中 union 和 union all 的用法

如果我们需要将两个 select 语句的结果作为一个整体显示出来,我们就需要用到 union 或者 union all 关键字。union (或称为联合)的作用是将多个结果合并在一起显示出来。

unionunion all 的区别是,union 会自动压缩多个结果集合中的重复结果,而 union all 则将所有的结果全部显示出来,不管是不是重复。

union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;union 在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表 union
如下sql:

SELECT create_time FROM `e_msku_sku` WHERE msku = '21-BQLEDNL120W-BK'
UNION
SELECT create_time FROM `e_msku_sku` WHERE msku = '21-BQLEDNL120W-BK'

结果:

union all:对两个结果集进行并集操作,包括重复行,不进行排序; 如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
如下sql:

SELECT create_time FROM `e_msku_sku` WHERE msku = '21-BQLEDNL120W-BK'
UNION ALL
SELECT create_time FROM `e_msku_sku` WHERE msku = '21-BQLEDNL120W-BK'

结果:

2. 注意事项

2.1、UNION 和 UNION ALL 内部的 SELECT 语句必须拥有相同数量的列

2.2、每条 SELECT 语句中列的顺序必须相同

  • 先来说下,如果顺序不同,会是什么结果?
    答:结果字段的顺序以union all 前面的表字段顺序为准。
    union all 后面的表的数据会按照顺序依次附在后面。注意:按照字段顺序匹配,而不是按照字段名称匹配。

  • sql如下:顺序对结果的影响

SELECT * 
FROM(
	SELECT msku,create_time FROM `e_msku_sku` WHERE msku = '21-BQLEDNL120W-BK'
UNION ALL
	SELECT create_time,msku FROM `e_msku_sku` WHERE msku = '21-BQLEDNL120W-BK') t

综上:

union all 结果字段的顺序以 union all 前面的表字段顺序为准。union all 后面的表的数据会按照字段顺序依次附在后面,而不是按照字段名称匹配。

我们上面以*来表示顺序的不同,其实你写成不同顺序的字段结果一致。

3. union all 使用场景

  • sql 中的组合in,可用 union all 来代替,提高查询效率

修改前:组合in sql

SELECT ***, ***, ***, ***, ***
FROM e_rating_info 
WHERE rating_quantity <> 0 AND (***, ***) 
IN (('***', '***'), ('***', '***'), 
('***', '***'), ('***', '***'), 
('***', '***'), ('***', '***'), 
('***', '***'), ('***', '***'), 
('***', '***'), ('***', '***')) 
ORDER BY *** DESC

修改后:UNION ALL sql

<select id="queryRatingInfo" resultType="***">
        <foreach collection="ratingList" item="item" index="index" open="" separator="UNION ALL" close="">
            SELECT ***, ***, ***, ***, ***
            FROM e_rating_info
            WHERE rating_quantity &lt;&gt; 0
            AND country_code = #item.***
            AND asin = #item.***
        </foreach>
        ORDER BY *** DESC;
    </select>

另外,如果系统中进行了分表,一定要保证各个表的字段顺序一致。特别是修改的时候。否则,如果使用 *汇总查询结果,肯定是会有问题的…亲身踩坑。

MYSQL union 和union all 用法 /

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。

请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。去重,操作符选取不同的值

UNION ALL 顾名思义 unionall 显示全部 UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。

-- 案卷总数
SELECT
	count( t.id ) AS tiaoshu 
FROM
	grid_case_his t 
WHERE
	t.BELONG_TOWN LIKE CONCAT_WS( '111', '', '%' ) UNION ALL-- 	立案数
SELECT
	count( l.id ) AS tiaoshu 
FROM
	grid_case_his l 
WHERE
	l.CASE_REGISTE_TIME > 0 
	AND l.BELONG_TOWN LIKE CONCAT_WS( '111', '', '%' ) UNION ALL-- 			结案数
SELECT
	count( j.id ) AS tiaoshu 
FROM
	grid_case_his j 
WHERE
	j.CASE_STATUS = 'case_status_logoff' 
	AND j.BELONG_TOWN LIKE CONCAT_WS( '111', '', '%' ) UNION ALL-- 			返工数
SELECT
	count( d.id ) AS tiaoshu 
FROM
	grid_case_his d 
WHERE
	d.CASE_STATUS = 'case_status_rebut' 
	AND d.BELONG_TOWN LIKE CONCAT_WS( '111', '', '%' ) UNION ALL-- 				在办
SELECT
	count( k.id ) AS tiaoshu 
FROM
	grid_case_his k 
WHERE
	k.`CASE_STATUS` != 'case_status_logoff' 
	AND k.BELONG_TOWN LIKE CONCAT_WS( '111', '', '%' ) UNION ALL-- 				超期案件
SELECT
	count( v.id ) AS tiaoshu 
FROM
	grid_case_his v 
WHERE
	v.`CASE_STATUS` != 'case_status_logoff' 
	AND CURDATE() > v.CASE_LIMIT_TIME 
	AND v.BELONG_TOWN LIKE CONCAT_WS( '111', '', '%' ) 
	LIMIT 1000
	

CURDATE() > v.CASE_LIMIT_TIME
CURDATE() : 当前时间
CONCAT_WS :字符串拼接 类似于 like 111% 以111开头的

可参考W3C

以上是关于mysql的union和union all的主要内容,如果未能解决你的问题,请参考以下文章

mysql union和union all的区别

mysql union和union all的区别

mysql union和union all的区别

mysql中的union用法

mysql union all和union的区别

Mysql联合查询UNION和UNION ALL的使用介绍