一 知识点
1.1 UNION 用于合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行。
UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。
同时,每条 SELECT 语句中的列的顺序必须相同.
即 UNION在进行表连接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。
UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
UNION 语法:
SELECT 字段名FROM 表1 UNION SELECT 字段名 FROM 表2;
这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序
UNION ALL 语法:
SELECT 字段名FROM 表1 UNION ALL SELECT 字段名 FROM 表2;
另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
注意:
1、UNION 结果集中的列名总是等于第一个 SELECT 语句中的列名
2、UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。
同时,每条 SELECT 语句中的列的顺序必须相同。
3、 一般地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
二 举例
2.1 UNION 用法
mysql > SELECT A.USER_ID, A.USER_NAME FROM a AS A
UNION SELECT B.PRODUCT_ID,B.PRODUCT_NAME FROM b AS B
或
mysql > SELECT T.* FROM ( SELECT A.USER_ID, A.USER_NAME FROM a AS A
UNION SELECT B.PRODUCT_ID, B.PRODUCT_NAME FROM b AS B ) AS T
2.2 UNION ALL 用法
mysql > SELECT T.* FROM ( SELECT A.USER_ID, A.USER_NAME FROM a AS A
三 注意事项
union:联合的意思,即把两次或多次查询结果合并起来。
要求:两次查询的列数必须一致
推荐:列的类型可以不一样,但推荐查询的每一列,想对应的类型以一样可以来自多张表的数据:
多次sql语句取出的列名可以不一致,此时以第一个sql语句的列名为准。
如果不同的语句中取出的行,有完全相同(这里表示的是每个列的值都相同),那么union会将相同的行合并,最终只保留一行。也可以这样理解,union会去掉重复的行。
如果不想去掉重复的行,可以使用union all。如果子句中有order by,limit,需用括号()包起来。推荐放到所有子句之后,即对最终合并的结果来排序或筛选。
如:
mysql > (select * from a order by product_id) union (select * from b order product_id);
在子句中,order by 需要配合limit使用才有意义。如果不配合limit使用,会被语法分析器优化分析时去除。
四 使用实例
1)查询两张表的集合,求和
语法: 已知 表A,表B两张表
select * from (select column AS col from A where 查询条件 ) AS a UNION ALL (select column AS col from B where 查询条件) ORDER by 排序字段 limit 0,20
SELECT
*
FROM
(
SELECT
RECHARGE_MENOY AS trande_money,
'充值' AS trande_type,
RECHARGE_STATUS AS trande_status,
RECHARGE_TIME AS trande_time
FROM
AC_RECHARGE
WHERE
RECHARGE_USERID = 'c3f19f5deef044fd91c933012327ef85'
AND (
CREATE_GMT > '2014-09-25 15:09:49'
OR UPDATE_GMT > '2014-09-25 15:09:49'
)
AND (
CREATE_GMT < '2015-03-25 15:09:49'
OR UPDATE_GMT < '2015-03-25 15:09:49'
)
) AS a
UNION ALL
(
SELECT
CASH_MENOY AS trande_money,
'提现' AS trande_type,
CASH_STATUS AS trande_status,
UPDATE_GMT AS trande_time
FROM
AC_CASH
WHERE
CASH_USERID = 'c3f19f5deef044fd91c933012327ef85'
AND (
CREATE_GMT > '2014-09-25 15:15:09'
OR UPDATE_GMT > '2014-09-25 15:15:09'
)
AND (
CREATE_GMT < '2015-03-25 15:15:09'
OR UPDATE_GMT < '2015-03-25 15:15:09'
)
)
ORDER BY
trande_time DESC
LIMIT 0,20
2)统计两张表的个数,然后再求和
语法:
select sum(num) from (select count(*) as num from A where 查询条件 UNION ALL select count(*) as num from B where 查询条件) AS b
SELECT
sum(num)
FROM
(
SELECT
count(*) AS num
FROM
AC_RECHARGE
WHERE
RECHARGE_USERID = 'c3f19f5deef044fd91c933012327ef85'
AND (
CREATE_GMT > '2014-09-25 15:09:49'
OR UPDATE_GMT > '2014-09-25 15:09:49'
)
AND (
CREATE_GMT < '2015-03-25 15:09:49'
OR UPDATE_GMT < '2015-03-25 15:09:49'
)
UNION ALL
SELECT
count(*) AS num
FROM
AC_CASH
WHERE
CASH_USERID = 'c3f19f5deef044fd91c933012327ef85'
AND (
CREATE_GMT > '2014-09-25 15:15:09'
OR UPDATE_GMT > '2014-09-25 15:15:09'
)
AND (
CREATE_GMT < '2015-03-25 15:15:09'
OR UPDATE_GMT < '2015-03-25 15:15:09'
)
) AS b
3)ibatis配置: