Union All 使用注意事项和字段顺序不一致导致的异常
使用注意,先说结果:
UNION 操作符用于合并两个或多个 SELECT 语句的结果集,这里需要注意的是:
- UNION 内部的 SELECT 语句必须拥有相同数量的列;
- 列也必须拥有相似的数据类型(实际非必须);
- 同时,每条 SELECT 语句中列的顺序必须相同。
一、表结构数据准备如下:
1.1 test_union_1
结构:
CREATE TABLE `test_union_1` (
`one` varchar(255) DEFAULT NULL,
`two` varchar(255) DEFAULT NULL,
`three` varchar(255) DEFAULT NULL,
`four` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
数据:
1.2 test_union_2
结构:
CREATE TABLE `test_union_2` (
`four` varchar(255) DEFAULT NULL,
`three` varchar(255) DEFAULT NULL,
`two` varchar(255) DEFAULT NULL,
`one` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
数据:
两表数据一致,字段一致,只是字段顺序不同。
test_union_1
的顺序:one,two,three,four
test_union_2
的顺序:four,three,two,one
二、验证
2.1、验证:UNION 内部的 SELECT 语句必须拥有相同数量的列;
2.2、验证:列也必须拥有相似的数据类型(实际非必须);
这个实际非必须。
修改表test_union_2
结构如下:String类型改为int类型。
CREATE TABLE `test_union_2` (
`four` int(255) DEFAULT NULL,
`three` int(255) DEFAULT NULL,
`two` int(255) DEFAULT NULL,
`one` int(255) DEFAULT NULL
) ENGINE = InnoDB CHARSET = latin1;
查询:
SELECT *
FROM (
SELECT one, two, three, four
FROM test_union_1
UNION ALL
SELECT one, two, three, four
FROM test_union_2
) T;
结果:
所以,实际不是字段类型必须一致,只要可以转换即可。具体转换逻辑暂时不清楚,后续遇到了再搞。
2.3、验证:每条 SELECT 语句中列的顺序必须相同(亲身踩坑)。
先来说下,如果顺序不同,会是什么结果?
答:结果字段的顺序以 union all
前面的表字段顺序为准。
union all
后面的表的数据会按照顺序依次附在后面。注意:按照字段顺序匹配,而不是按照字段名称匹配。
测试如下:表顺序对结果的影响
2.1 test_union_1
UNION ALL test_union_2
SELECT *
FROM (
SELECT *
FROM test_union_1
UNION ALL
SELECT *
FROM test_union_2
) T;
结果:
可发现:结果字段是test_union_1
的字段顺序:one,two,three,four
。
2.2 test_union_2
UNION ALL test_union_1
SELECT *
FROM (
SELECT *
FROM test_union_2
UNION ALL
SELECT *
FROM test_union_1
) T;
结果:
可发现:结果字段是test_union_2
的字段顺序:four,three,two,one
。
综上:union all
结果字段的顺序以 union all
前面的表字段顺序为准。union all
后面的表的数据会按照字段顺序依次附在后面,而不是按照字段名称匹配。
我们上面以*
来表示顺序的不同,其实你写成不同顺序的字段结果一致。我亲测如此,但是不重复贴结果了。
另外,如果系统中进行了分表,一定要保证各个表的字段顺序一致。特别是修改的时候。否则,如果使用 *
汇总查询结果,肯定是会有问题的...亲身踩坑。