一、出现错误的情况

(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. goroutine&waitgroup下载文件

    0.1.索引 https://blog.waterflow.link/articles/1663078266267 当我们下载一个大文件的时候,会因为下载时间太久而超时或者出错.那么我么我们可以利用g ...

  2. 「MySQL高级篇」MySQL锁机制 && 事务

    大家好,我是melo,一名大三后台练习生,最近赶在春招前整理整理发过的博客~! 引言 锁锁锁,到哪到离不开这桩琐事,并发琐事,redis琐事,如今是MySQL琐事,这其中琐事,还跟MySQL另一个重要 ...

  3. webpack优化项目

    在使用vue 构建项目的时候 ,会用到vue.js, vue-router.js, 等库,通常打包的话会将这些公用的代码打包的一个文件中,导致该文件过大影响加载的速度.那么可以考虑使用cdn 加速的方 ...

  4. 从0到1搭建redis6.0.7

    redis集群搭建 一.安装redis 源码安装: 1.下载源码包: wget http://download.redis.io/releases/redis-6.0.7.tar.gz 2.解压到指定 ...

  5. 【Zulip】邮件系统配置

    通过docker-compose(docker-zulip)部署Zulip实例时需要配置邮件系统 SETTING_ZULIP_ADMINISTRATOR: '...@qq.com' SETTING_E ...

  6. .NET应用开发之SQLServer常见问题分析

    日常我们开发.NET应用时会使用SQLServer数据库,对于SQLServer数据库的日常开发有一些技能和工具,准备给大家分享一下. 一.场景1:SQLServer死锁分析  执行以下SQL,启用S ...

  7. bootstrap-table参数

    table.bootstrapTable({ url:'/Home/geurl', //请求后台的URL(*) method:'get', //请求方式(*) toolbar:'#toolbar', ...

  8. 决策树(二):后剪枝,连续值处理,数据加载器:DataLoader和模型评估

    在上一篇文章中,我们实现了树的构造,在下面的内容中,我们将中心放在以下几个方面 1.剪枝 2.连续值处理 3.数据加载器:DataLoader 4.模型评估 一,后剪枝 • 为什么剪枝  –" ...

  9. phpexcel 上传

    <?php require_once(ROOTPATH . "inc/PHPExcel/PHPExcel.class.php");//PHPExcel//获取数据 $objP ...

  10. python选课系统项目详解

    选课系统项目详解 选课系统简介及分析 选课系统架构设计分析 选课系统目录设计 管理员视图 注册 登录 创建学校 创建课程 创建讲师 学生视图 注册 登录 选择学校 选择课程 查看分数 教师视图 登录 ...