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 ...
随机推荐
- goroutine&waitgroup下载文件
0.1.索引 https://blog.waterflow.link/articles/1663078266267 当我们下载一个大文件的时候,会因为下载时间太久而超时或者出错.那么我么我们可以利用g ...
- 「MySQL高级篇」MySQL锁机制 && 事务
大家好,我是melo,一名大三后台练习生,最近赶在春招前整理整理发过的博客~! 引言 锁锁锁,到哪到离不开这桩琐事,并发琐事,redis琐事,如今是MySQL琐事,这其中琐事,还跟MySQL另一个重要 ...
- webpack优化项目
在使用vue 构建项目的时候 ,会用到vue.js, vue-router.js, 等库,通常打包的话会将这些公用的代码打包的一个文件中,导致该文件过大影响加载的速度.那么可以考虑使用cdn 加速的方 ...
- 从0到1搭建redis6.0.7
redis集群搭建 一.安装redis 源码安装: 1.下载源码包: wget http://download.redis.io/releases/redis-6.0.7.tar.gz 2.解压到指定 ...
- 【Zulip】邮件系统配置
通过docker-compose(docker-zulip)部署Zulip实例时需要配置邮件系统 SETTING_ZULIP_ADMINISTRATOR: '...@qq.com' SETTING_E ...
- .NET应用开发之SQLServer常见问题分析
日常我们开发.NET应用时会使用SQLServer数据库,对于SQLServer数据库的日常开发有一些技能和工具,准备给大家分享一下. 一.场景1:SQLServer死锁分析 执行以下SQL,启用S ...
- bootstrap-table参数
table.bootstrapTable({ url:'/Home/geurl', //请求后台的URL(*) method:'get', //请求方式(*) toolbar:'#toolbar', ...
- 决策树(二):后剪枝,连续值处理,数据加载器:DataLoader和模型评估
在上一篇文章中,我们实现了树的构造,在下面的内容中,我们将中心放在以下几个方面 1.剪枝 2.连续值处理 3.数据加载器:DataLoader 4.模型评估 一,后剪枝 • 为什么剪枝 –" ...
- phpexcel 上传
<?php require_once(ROOTPATH . "inc/PHPExcel/PHPExcel.class.php");//PHPExcel//获取数据 $objP ...
- python选课系统项目详解
选课系统项目详解 选课系统简介及分析 选课系统架构设计分析 选课系统目录设计 管理员视图 注册 登录 创建学校 创建课程 创建讲师 学生视图 注册 登录 选择学校 选择课程 查看分数 教师视图 登录 ...