UNION,UNION ALL 的详细用法

发布时间:2026/7/17 12:55:44
UNION,UNION ALL 的详细用法 目录一、基本概念二、核心区别三、语法使用规则四、代码实际演示4.1 两张表字段相同字段顺序也相同4.2 两张表字段相同。但字段顺序不同4.3 两张表存在相同字段但一张表字段多一张表字段少一、基本概念操作符功能描述去重处理性能对比UNION合并多个查询结果自动去除重复行是较低需排序去重UNION ALL合并多个查询结果保留所有行包括重复行否较高二、核心区别对比维度UNIONUNION ALL重复数据处理自动去重保留所有重复行执行效率较慢需排序和去重较快直接合并结果资源消耗高涉及临时表排序低排序行为结果集默认无明确顺序结果集默认无明确顺序适用场景需唯一结果的合并需保留所有记录的合并总之记住一句话UNION 会去重效率低UNION ALL 不去重效率高二者都不会自动排序。三、语法使用规则UNION 和 UNION ALL 语法规则是一样的如下实例SQL-- UNION 语法 SELECT column1, column2 FROM table1 UNION SELECT column1, column2 FROM table2; -- 这里使用了 column1, column2将字段一一列出来如果 table1和table2字段的顺序一致可以直接写为 select * 下方 UNION ALL 同理 select * from table1 UNION SELECT * FROM table2; -- 此外还可以在一张表使用union select * from table1 where ... union select * from table1 where ... -- UNION ALL 语法 SELECT column1, column2 FROM table1 UNION ALL SELECT column1, column2 FROM table2; 或 select * from table1 UNION ALL SELECT * FROM table2;但需要注意以下三点1列数必须一致所有 SELECT 语句的列数必须相同若表A存在字段a表B不存在字段a则需要给一个默认值通常给NULL或空字符串2数据类型兼容对应列的数据类型需兼容如 VARCHAR 与 TEXT 兼容不兼容会报错3列名规则最终结果集的列名以第一个 SELECT 的列名为准。也可以为查询字段取别名实际开发过程中通常与响应结果实体类字段名称一致四、代码实际演示4.1 两张表字段相同字段顺序也相同user1 表数据如下图user2 表数据如下图此时 user1 和 user2 两个表字段完全相同但数据略有不同两张表都有相同的 张三、李四、王五1使用 UNION结果如下图。因为两张表的张三、李四、王五 完全相同所以 UNION 帮我们自动去重了查询合并后的结果就是7条数据2使用 UNION ALL结果如下图。UNION ALL 不会自动去重而是将两张表的全部数据合并一共十条数据4.2 两张表字段相同。但字段顺序不同user1 用户表1数据如下图user4 用户表4数据如下图此时由于两张表字段顺序我们不能直接使用 select * 虽然usernamepassword 都是 VARCHAR 类型可以兼容但是查询到的数据会报错如下图不管是 UNION还是UNION ALL最终的表字段顺序会以第一张表 user1 的字段顺序为准这就会产生一个问题我 user4 表中passwor 和 username 顺序是反着的因为没有转化就会导致查询到的结果中user4 表的查询结果用户的密码 password 被当作 username用户的 username 被当作 password造成数据错误。这种情况下我们就不能直接使用 SELECT *而是需要将字段一一对应。如下图中代码所示我们需要将字段一一列出并让两张表的字段顺序也与之对应我这里使用 AS 关键字取别名实际开发过程中也较为常见有时候 table1 用户名字段可能为 usernametable2 表中用户名字段可能为 name我们就为查询结果的虚拟表字段取别名方便我们理解。4.3 两张表存在相同字段但一张表字段多一张表字段少这也是一种较为常见的情况比如我 table1 表中有 ABC三个字段table2 有ABCD四个字段我希望对这两张表UNION合并取出查询结果。如下为 user1 表数据如下为 user3 表数据与之对比user3 少了一个 age 年龄字段。此时我们如果使用 SELECT * 去 查询会报错。如下图报错称两张表有不同数量的列。此时我们就需要补列字段 因为 user3 没有 age 字段我们要在查询结果中进行填充如下我们使用 NULL AS age对查询结果中 user3 的age字段进行填充使其全部为 NULL这样就可以与 user1 进行UNION 或 UNION ALL啦当然我们也可以不使用 NULL 进行填充使用任何数据都可以。例如空字符串这样一来查询结果就全部都是空字符串了。也可以使用具体数据比如 age 为年龄我们就让没有这个字段的全部默认填充为 18。如下图OK小伙伴们以上三种情况基本上涵盖了多表进行 UNIONUNION ALL 的全部情况啦建表SQL放在下面了有需要自己动手尝试的小伙伴自取即可。SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0; -- ---------------------------- -- Table structure for user1 -- ---------------------------- DROP TABLE IF EXISTS user1; CREATE TABLE user1 ( uid int NOT NULL, username varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, password varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, age int NULL DEFAULT NULL, PRIMARY KEY (uid) USING BTREE ) ENGINE InnoDB CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ROW_FORMAT Dynamic; -- ---------------------------- -- Records of user1 -- ---------------------------- INSERT INTO user1 VALUES (1, 张三, 123, 17); INSERT INTO user1 VALUES (2, 李四, 1234, 18); INSERT INTO user1 VALUES (3, 王五, 12345, 18); INSERT INTO user1 VALUES (4, 赵六, 12346, 19); INSERT INTO user1 VALUES (5, 123, 12345, 20); DROP TABLE IF EXISTS user2; CREATE TABLE user2 ( uid int NOT NULL, username varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, password varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, age int NULL DEFAULT NULL, PRIMARY KEY (uid) USING BTREE ) ENGINE InnoDB CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ROW_FORMAT Dynamic; -- ---------------------------- -- Records of user2 -- ---------------------------- INSERT INTO user2 VALUES (1, 张三, 123, 17); INSERT INTO user2 VALUES (2, 李四, 1234, 18); INSERT INTO user2 VALUES (3, 王五, 12345, 18); INSERT INTO user2 VALUES (4, 赵六, 12345, 19); INSERT INTO user2 VALUES (5, 123456, 123454536, 21); DROP TABLE IF EXISTS user3; CREATE TABLE user3 ( uid int NOT NULL, username varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, password varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, PRIMARY KEY (uid) USING BTREE ) ENGINE InnoDB CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ROW_FORMAT Dynamic; -- ---------------------------- -- Records of user3 -- ---------------------------- INSERT INTO user3 VALUES (1, 张三, 123); INSERT INTO user3 VALUES (2, 李四, 1234); INSERT INTO user3 VALUES (4, 赵六, 12346); INSERT INTO user3 VALUES (5, 123456, 123454536); DROP TABLE IF EXISTS user4; CREATE TABLE user4 ( uid int NOT NULL, password varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, username varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, age int NULL DEFAULT NULL, PRIMARY KEY (uid) USING BTREE ) ENGINE InnoDB CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ROW_FORMAT Dynamic; -- ---------------------------- -- Records of user4 -- ---------------------------- INSERT INTO user4 VALUES (1, afd‘, ewfew, 11); INSERT INTO user4 VALUES (2, defg, ergegwr, 19); INSERT INTO user4 VALUES (3, fdgg, fwe, 55); INSERT INTO user4 VALUES (4, 而我4, 3544, 18); INSERT INTO user4 VALUES (5, 12345, 123, 20); SET FOREIGN_KEY_CHECKS 1;