MySQL union 和 order by 同时使用
一、出现错误的情况
(1)使用 union 和 多个order by 不加括号 报错
(2)order by 在 union 连接的子句不起作用
二、解决上述问题的两种方法
(1)order by 在 union 连接的子句的子句中使用
(2)先使用 union 后使用order by
三、案例分析:
我们举个例子进行说明,案例来自:SQL132 每个题目和每份试卷被作答的人数和次数
描述
现有试卷作答记录表exam_record(uid用户ID, exam_id试卷ID, start_time开始作答时间, submit_time交卷时间, score得分):
id | uid | exam_id | start_time | submit_time | score |
---|---|---|---|---|---|
1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:41:01 | 81 |
2 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
3 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 80 |
4 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
5 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 85 |
6 | 1002 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
题目练习表practice_record(uid用户ID, question_id题目ID, submit_time提交时间, score得分):
id | uid | question_id | submit_time | score |
---|---|---|---|---|
1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
5 | 1003 | 8001 | 2021-08-02 19:38:01 | 70 |
6 | 1003 | 8001 | 2021-08-02 19:48:01 | 90 |
7 | 1003 | 8002 | 2021-08-01 19:38:01 | 80 |
请统计每个题目和每份试卷被作答的人数和次数,分别按照"试卷"和"题目"的uv & pv降序显示,示例数据结果输出如下:
tid | uv | pv |
---|---|---|
9001 | 3 | 3 |
9002 | 1 | 3 |
8001 | 3 | 5 |
8002 | 2 | 2 |
解释:“试卷”有3人共练习3次试卷9001,1人作答3次9002;“刷题”有3人刷5次8001,有2人刷2次8002。
求解:
分析思路
难点:
1.union 和 order by 同时使用需要注意的问题
(1)统计每份试卷被作答的人数和次数
[条件]:where score >= 85 and year(start_time) = 2021
[使用]:distinct。一定要去重
(2)统计每个题目被作答的人数和次数
[条件]:where difficulty = 'hard' and score > 80 and year(start_time) = 2021 and timestampdiff(minute, start_time, submit_time) < duration / 2
[使用]:多表连接使用 join using( )
(3)合并两个表,分别按照"试卷"和"题目"的uv & pv降序显示
- [使用]:union all 和union 都可以,因为列activity不会有重复。
最终结果
select * from
(
select 查询结果 [试卷ID; 作答次数]
from 从哪张表中查询数据[试卷作答记录表]
group by 分组条件 [试卷ID]
order by 对查询结果排序 [按照"试卷"的uv & pv降序]
)
union
select * from
(
select 查询结果 [题目ID; 作答次数]
from 从哪张表中查询数据[题目练习表]
group by 分组条件 [题目ID]
order by 对查询结果排序 [按照"题目"的uv & pv降序]
)
常见的错误解法
(1)使用 union 和 多个order by 不加括号 【报错】
select
exam_id as tid,
count(distinct uid) as uv,
count(uid) as pv
from exam_record a
group by exam_id
order by uv desc, pv desc
union
select
question_id as tid,
count(distinct uid) as uv,
count(uid) as pv
from practice_record b
group by question_id
order by uv desc, pv desc
执行出错
程序异常退出, 请检查代码"是否有数组越界等异常"或者"是否有语法错误"
SQL_ERROR_INFO: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'union all\n\nselect \n question_id as tid,\n count(distinct uid) as uv,\n co' at line 11"
这是因为union在没有括号的情况下只能有一个order by。为什么只能有一个order by 呢?
既然不加括号出错,那我就加上括号使用2个order by !
(2)order by 在 union 子句中不起作用
(select
exam_id as tid,
count(distinct uid) as uv,
count(uid) as pv
from exam_record a
group by exam_id
order by uv desc, pv desc)
union
(select
question_id as tid,
count(distinct uid) as uv,
count(uid) as pv
from practice_record b
group by question_id
order by uv desc, pv desc)
结果发现这样写order by在每个子表中不起作用!所以这种方法也不对。但是 union 可以在子句的子句中起作用,写成下面这样:
正确解法
方法一:
(1)order by 在 union 连接的子句的子句中使用
#正确代码
select * from
(
select
exam_id as tid,
count(distinct uid) as uv,
count(uid) as pv
from exam_record a
group by exam_id
order by uv desc, pv desc
) a
union
select * from
(
select
question_id as tid,
count(distinct uid) as uv,
count(uid) as pv
from practice_record b
group by question_id
order by uv desc, pv desc
) attr
那我是不是可以union两个子句之后再使用order by ,但是这个排序要对2个表分别进行降序,就需要写成下面这样:
方法二:
(2)先使用 union 后使用order by
使用函数
left(str,length) 函数: str左边开始的长度为 length 的子字符串,在本例中为‘9’和‘8’
解释:试卷编号以‘9’开头、题目编号以‘8’开头,对编号进行降序就是对"试卷"和"题目"分别进行排序
(
#每份试卷被作答的人数和次数
select
exam_id as tid,
count(distinct uid) as uv,
count(*) as pv
from exam_record
group by exam_id
)
union
(
#每个题目被作答的人数和次数
select
question_id as tid,
count(distinct uid) as uv,
count(*) as pv
from practice_record
group by question_id
)
#分别按照"试卷"和"题目"的uv & pv降序显示
order by left(tid,1) desc,uv desc,pv desc
推荐使用方法一,更具有普适性。
MySQL union 和 order by 同时使用的更多相关文章
- MySql union与order by
[MySql union与order by] 如果您想使用ORDER BY或LIMIT子句来对全部UNION结果进行分类或限制,则应对单个地SELECT语句加圆括号,并把ORDER BY或LIMIT放 ...
- MySQL中union和order by一起使用的方法
MySQL中union和order by是可以一起使用的,但是在使用中需要注意一些小问题,下面通过例子来说明.首先看下面的t1表. 1.如果直接用如下sql语句是会报错:Incorrect usage ...
- MYSQL之union和order by分析([Err] 1221 - Incorrect usage of UNION and ORDER BY)
我在一个业务中采用了按月的分表策略,当查询的条件跨月的时候,使用了union all汇总2个表的数据,并按插入时间倒序排列.查询并不复杂,但是当执行的时候却报错了. SELECT * FROM `ta ...
- mysql 错误 1221 Incorrect usage of union and order by
今天有个项目出现了问题 问题原因是union和order by 的问题.关于这个问题的解决方案可以猛击下面的链接. http://blog.csdn.net/gtuu0123/article/deta ...
- mysql中group by和order by同时使用无效的替代方案
前言 最近一年由于工作需要大部分使用的都是NoSql数据库,对关系型数据库感觉越来越陌生,一个由group by和order by 引发的血案由此而生.在此做个记录,以备不时之需. 需求 首先,看一下 ...
- mysql中的union和order by、limit
我有一个表 CREATE TABLE `test1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) N ...
- 同时使用Union和Order by问题(ORA-00933错误)解决
之前,同事在编写视图的过程中遇到这样了这个错误.我把简化后的语句整理如下: 1: select 2: '2016' as nf, 3: qxdm, 4: round(sum(tbdlmj)/10000 ...
- mysql union 与 union all 语法及用法
1.mysql union 语法 mysql union 用于把来自多个select 语句的结果组合到一个结果集合中.语法为: select column,......from tabl ...
- 十七、MySQL UNION 操作符
MySQL UNION 操作符 本教程为大家介绍 MySQL UNION 操作符的语法和实例. 描述 MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中.多 ...
- MySQL UNION 查询
UNION 用来合并多个 SELECT 结果. 考察如下两个表: # t1 +----+---------+ | id | pattern | +----+---------+ | 1 | Divot ...
随机推荐
- 「MySQL高级篇」MySQL锁机制 && 事务
大家好,我是melo,一名大三后台练习生,最近赶在春招前整理整理发过的博客~! 引言 锁锁锁,到哪到离不开这桩琐事,并发琐事,redis琐事,如今是MySQL琐事,这其中琐事,还跟MySQL另一个重要 ...
- 开源网络协议栈onps诞生记
小孩没娘,说来话长,一切都要从LwIP说起.大约是06年9月,本人在二姨的坛口发布了一篇小文--<uC/OS-II 平台下的 LwIP 移植笔记>.自此一发不可收拾,开启了一段我与LwIP ...
- 开源项目在线化 中文繁简体转换/敏感词/拼音/分词/汉字相似度/markdown 目录
前言 以前在 github 上自己开源了一些项目.碍于技术与精力,大部分项目都是 java 实现的. 这对于非 java 开发者而言很不友好,对于不会编程的用户更加不友好. 为了让更多的人可以使用到这 ...
- for in 和 for of 的区别和v-for指令的三种使用方法
for...in 循环:只能获得对象的键名,不能获得键值 for...of 循环:允许遍历获得键值 var arr = ['red', 'green', 'blue'] for(let item in ...
- 定制ASP.NET Core的身份认证
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 在本章,我们将学习如何定制ASP.NET Core认证机制.微软把安全认证当做AS ...
- 使用kubeadm方式搭建K8S集群
使用kubeadm方式搭建K8S集群 kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Ma ...
- 2022春每日一题:Day 33
题目:[USACO 6.1.3] Cow XOR 没找到这题具体网址,这个题就是求最大异或区间(总长度尽量小,右端点尽量大) 嗯很显然一个[l,r]的异或和=s[r]s[l-1],那么现在有了优秀的n ...
- 回溯算法经典问题总结(.NET版)
回溯算法 回溯法其实也是一种递归,本质上就是穷举,然后筛选出符合规则的数据.为了使回溯更加高效,我们根据规则要求,在穷举过程中加上条件限制(也就是剪枝). 我们什么场景下应该想到使用回溯法呢? 如何画 ...
- 【云原生 · Kubernetes】部署Kubernetes集群
[云原生 · Kubernetes]搭建Harbor仓库 接着上次的内容,后续来了! 在master节点执行脚本k8s_master_install.sh即可完成K8S集群的部署,具体步骤参考如下(1 ...
- i春秋Hello World
打开只有一句hello world,直接查看源码,发现一个flag.xmas.js文件 试试直接访问http://106.75.72.168:9999/flag.xmas.js http://106 ...