一、出现错误的情况

(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 同时使用的更多相关文章

  1. MySql union与order by

    [MySql union与order by] 如果您想使用ORDER BY或LIMIT子句来对全部UNION结果进行分类或限制,则应对单个地SELECT语句加圆括号,并把ORDER BY或LIMIT放 ...

  2. MySQL中union和order by一起使用的方法

    MySQL中union和order by是可以一起使用的,但是在使用中需要注意一些小问题,下面通过例子来说明.首先看下面的t1表. 1.如果直接用如下sql语句是会报错:Incorrect usage ...

  3. MYSQL之union和order by分析([Err] 1221 - Incorrect usage of UNION and ORDER BY)

    我在一个业务中采用了按月的分表策略,当查询的条件跨月的时候,使用了union all汇总2个表的数据,并按插入时间倒序排列.查询并不复杂,但是当执行的时候却报错了. SELECT * FROM `ta ...

  4. mysql 错误 1221 Incorrect usage of union and order by

    今天有个项目出现了问题 问题原因是union和order by 的问题.关于这个问题的解决方案可以猛击下面的链接. http://blog.csdn.net/gtuu0123/article/deta ...

  5. mysql中group by和order by同时使用无效的替代方案

    前言 最近一年由于工作需要大部分使用的都是NoSql数据库,对关系型数据库感觉越来越陌生,一个由group by和order by 引发的血案由此而生.在此做个记录,以备不时之需. 需求 首先,看一下 ...

  6. mysql中的union和order by、limit

      我有一个表 CREATE TABLE `test1` (  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  `name` varchar(20) N ...

  7. 同时使用Union和Order by问题(ORA-00933错误)解决

    之前,同事在编写视图的过程中遇到这样了这个错误.我把简化后的语句整理如下: 1: select 2: '2016' as nf, 3: qxdm, 4: round(sum(tbdlmj)/10000 ...

  8. mysql union 与 union all 语法及用法

    1.mysql   union  语法 mysql   union 用于把来自多个select  语句的结果组合到一个结果集合中.语法为: select  column,......from tabl ...

  9. 十七、MySQL UNION 操作符

    MySQL UNION 操作符 本教程为大家介绍 MySQL UNION 操作符的语法和实例. 描述 MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中.多 ...

  10. MySQL UNION 查询

    UNION 用来合并多个 SELECT 结果. 考察如下两个表: # t1 +----+---------+ | id | pattern | +----+---------+ | 1 | Divot ...

随机推荐

  1. 十七、Job与Cronjob

    Job 与 Cronjob 一.Job ​Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束. 特殊说明: 1.spec.template 格式同 Pod ​2 ...

  2. 实验6:开源控制器实———RYU

    一.实验目的 1.能够独立部署RYU控制器: 2.能够理解RYU控制器实现软件定义的集线器原理: 3.能够理解RYU控制器实现软件定义的交换机原理. 二.实验环境 Ubuntu 20.04 Deskt ...

  3. Aspose.Cell和NPOI生成Excel文件2

    NPOI还是比较好用的,引用dll程序集即可 1创建workbook和工作流 HSSFWorkbook workbook = new HSSFWorkbook(); MemoryStream ms = ...

  4. freeswitch的mod_curl模块

    概述 有时候,我们需要在呼叫的过程中,或过程后调用web api接口. freeswitch的mod_curl模块可以很方便的实现web api的接口调用. mod_curl模块默认不安装,需要进入模 ...

  5. ModuleNotFoundError: No module named 'XXX'

    先来一张表情包: pycharm在小黑框使用pip安装某个包,在解释器没有找到某个包,所以运行程序的时候总是报错. 我相信大家可能都遇到这样的问题. 我下载有3.8.3.10版本的python,我py ...

  6. 【云原生 · Kubernetes】Kubernetes容器云平台部署与运维

    [题目1]Deployment管理 在master节点/root目录下编写yaml文件nginx-deployment.yaml,具体要求如下: (1)Deployment名称:nginx-deplo ...

  7. kotlin的suspend对比csharp的async&await

    协程的出现大大降低了异步编程的复杂度,可以让我们像写同步代码一样去写异步代码,如果没有它,那么很多异步的代码都是需要靠回调函数来一层层嵌套,这个在我之前的一篇有介绍 rxjava回调地狱-kotlin ...

  8. 写一个linux平台的桌面宠物

    效果图 前言 我一直在用python 写一下有趣的东西,让编程不那么无聊,之前一直有写一个桌面宠物的想法,无奈这些都是依赖资源文件,没有图片资源没办法写里面的逻辑,直到我看见了 shimiji手机桌面 ...

  9. SQL注入漏洞原理与利用

    SQL注入漏洞原理与利用 SQL注入漏洞流程 判断注入类型 判断字段个数 查询回显位 查询数据库名 查询表.字段名 查询内容 判断注入类型 1.数字型注入点判断 当要输入的参数x为数字型时,后端脚本中 ...

  10. 【机器学习】李宏毅——AE自编码器(Auto-encoder)

    1.What 在自编码器中,有两个神经网络,分别为Encoder和Decoder,其任务分别是: Encoder:将读入的原始数据(图像.文字等)转换为一个向量 Decoder:将上述的向量还原成原始 ...