MySQL使⽤UNION连接两个查询排序失效
概述
UNION
连接数据集关键字,可以将两个查询结果集拼接为⼀个,会过滤掉相同的记录
UNION ALL
连接数据集关键字,可以将两个查询结果集拼接为⼀个,不会过滤掉相同的记录
今天在接到⼀个需求的时候使⽤了UNION进⾏查询后发现,如果两个查询分别使⽤ORDER BY后拼接居然⽆法成功排序,经过了好⼀番折腾,记录下web前端工程师是干嘛的
表结构及数据
-- 创建表
CREATE TABLE test_user (
ID int(11) NOT NULL AUTO_INCREMENT,
USER_ID int(11) DEFAULT NULL COMMENT '⽤户账号',
USER_NAME varchar(255) DEFAULT NULL COMMENT '⽤户名',
AGE int(5) DEFAULT NULL COMMENT '年龄',
COMMENT varchar(255) DEFAULT NULL COMMENT '简介',
PRIMARY KEY (ID)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-- 数据插⼊语句
INSERT INTO test_user (ID, USER_ID, USER_NAME, AGE, COMMENT) VALUES ('1', '111', '开⼼菜鸟', '18', '今天很开⼼');
INSERT INTO test_user (ID, USER_ID, USER_NAME, AGE, COMMENT) VALUES ('2', '222', '悲伤菜鸟', '21', '今天很悲伤');
INSERT INTO test_user (ID, USER_ID, USER_NAME, AGE, COMMENT) VALUES ('3', '333', '认真菜
鸟', '30', '今天很认真');
INSERT INTO test_user (ID, USER_ID, USER_NAME, AGE, COMMENT) VALUES ('4', '444', '⾼兴菜鸟', '18', '今天很⾼兴');
INSERT INTO test_user (ID, USER_ID, USER_NAME, AGE, COMMENT) VALUES ('5', '555', '严肃菜鸟', '21', '今天很严肃');
默认表数据显⽰如下
ID USER_ID USER_NAME AGE COMMENT
1111开⼼菜鸟18今天很开⼼
2222悲伤菜鸟21今天很悲伤
3333认真菜鸟30今天很认真
4444⾼兴菜鸟18今天很⾼兴
5555严肃菜鸟21今天很严肃
运⾏结果分析
-- 查询1
SELECT
*
FROM
test_user u
ORDER BY AGE
结果集1
ID USER_ID USER_NAME AGE COMMENT 1111开⼼菜鸟18今天很开⼼4444⾼兴菜鸟18今天很愉快2222悲伤菜鸟21今天很悲伤5555严肃菜鸟21今天很严肃3333认真菜鸟30今天很认真
-- 查询2
-- 使⽤UNION
(
SELECT
*
FROM
test_user u
ORDER BY AGE
)
UNION
(
SELECT
*
不会英语可以学编程吗?
FROM
test_user u
ORDER BY AGE
);
-- 查询3
-- 使⽤UNION ALL
(
SELECT
*
FROM
test_user u
ORDER BY AGE
)
UNION ALL
(mysql安装教程菜鸟课程
SELECT
*
FROM
test_user u
ORDER BY AGE
)
结果集2:使⽤UNION
圣诞歌instrumental中文歌词由于UNION会合并相同的记录(与DISTINCT实现相同效果),因此此处显⽰仅有5条记录
ID USER_ID USER_NAME AGE COMMENT 1111开⼼菜鸟18今天很开⼼2222悲伤菜鸟21今天很悲伤3333认真菜鸟30今天很认真4444⾼兴菜鸟18今天很⾼兴5555严肃菜鸟21今天很严肃
结果集3:使⽤UNION ALL
ID USER_ID USER_NAME AGE COMMENT 1111开⼼菜鸟18今天很开⼼2222悲伤菜鸟21今天很悲伤3333认真菜鸟30今天很认真4444⾼兴菜鸟18今天很⾼兴5555严肃菜鸟21今天很严肃1111开⼼菜鸟18今天很开⼼2222悲伤菜鸟21今天很悲伤3333认真菜鸟30今天很认真4444⾼兴菜鸟18今天很⾼兴5555严肃菜鸟21今天很严肃如果需要使⽤UNION ALL⼜需要进⾏排序,则要将其作为⼀个⼦查询来查
-- 查询4
-- 将UNION ALL作为⼦查询并进⾏排序
SELECT
*
FROM
(
(
SELECT
*
FROM
test_user u
ORDER BY
AGE
)
UNION ALL
(
SELECT
*
FROM
test_user u
ORDER BY
AGE
)
) a
ORDER BY
AGE;
结果集4
ID USER_ID USER_NAME AGE COMMENT 1111开⼼菜鸟18今天很开⼼4444⾼兴菜鸟18今天很愉快1111开⼼菜鸟18今天很开⼼4444⾼兴菜鸟18今天很愉快2222悲伤菜鸟21今天很悲伤
ID USER_ID USER_NAME AGE COMMENT
5555严肃菜鸟21今天很严肃
2222悲伤菜鸟21今天很悲伤
5555严肃菜鸟21今天很严肃
3333认真菜鸟30今天很认真
3333认真菜鸟30今天很认真
改进
在经过⼀番搜索相关的经验后发现,是我之前有些画蛇添⾜了,原来可以在不使⽤⼦查询即可完成排序的⽅法:
-- 查询5
-- 第⼀个查询不使⽤排序,如果使⽤的话不加括号会报错(这也是我之前为什么会想⽤⼦查询的原因⽽没有想过这种⽅式了)
SELECT
*
FROM
test_user u
UNION ALL
SELECT
*
FROM
test_user u
ORDER BY
AGE
多线程编程的基本原理
运⾏出来的结果集与结果集4是相同的,此处就不再粘出结果。
结论
当我们使⽤UNION(或者UNION ALL)语句时,如果UNION的两个结果集在单独排序后再拼接,则他们的ORDER BY是失效的。如果我们要进⾏排序有以下两种⽅法:
1. 将它们作为⼦查询再ORDER BY查询⼀次(还是建议使⽤⽅法2,⼦查询太不简洁了)
fopen函数的初值2. 在第⼀个结果集中不使⽤排序,且不⽤括号分隔,⽽在第⼆个结果集后使⽤ORDER BY
参考链接
才疏学浅,如⽂中有错误,感谢⼤家指出。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。