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

  1. SELECT * FROM `table_201604` ORDER BY `REPORT_TIME` DESC
  2. UNION ALL
  3. SELECT * FROM `table_201605` ORDER BY `REPORT_TIME` DESC
  4. [Err] 1221 - Incorrect usage of UNION and ORDER BY

报错的原因,是不正确使用UNION和ORDER BY指令,为什么呢?经过一番查找资料,才知道MYSQL中UNION的语法是这样子的

  1. substatement union [all] substatement union [all] substatement [order by-clause] [limit-clause]

注意:

1. 每一个子句可以使用()包围,但是当第一个子句使用了()时,其它的子句都必须使用括号包围。

2. 每一个字句可以包含WHERE,GROUP BY,HAVING,JOIN,LIMIT,但是不能使用ORDER BY,如果需要使用ORDER BY,必须使用()包围子句。

接下来,做一些实验,能更好地理解,创建表和数据的SQL语句如下:

  1. CREATE TABLE `union_a` (
  2. `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  3. `T_NAME` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT ''COMMENT '所在表名称',
  4. `NUMBER` int(11) NOT NULL DEFAULT '0' COMMENT '用于排序',
  5. PRIMARY KEY (`ID`)
  6. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
  7. CREATE TABLE `union_b` LIKE `union_a`;
  8. INSERT INTO `union_a` VALUES ('1', 'a', '100');
  9. INSERT INTO `union_a` VALUES ('2', 'a', '28');
  10. INSERT INTO `union_a` VALUES ('3', 'a', '98');
  11. INSERT INTO `union_a` VALUES ('4', 'a', '19');
  12. INSERT INTO `union_a` VALUES ('5', 'a', '999');
  13. INSERT INTO `union_b` VALUES ('1', 'b', '23');
  14. INSERT INTO `union_b` VALUES ('2', 'b', '76');
  15. INSERT INTO `union_b` VALUES ('3', 'b', '32');
  16. INSERT INTO `union_b` VALUES ('4', 'b', '43');
  17. INSERT INTO `union_b` VALUES ('5', 'b', '11');

一、关于LIMIT

执行以下SQL语句

  1. SELECT * FROM `union_a` LIMIT 1
  2. UNION ALL
  3. SELECT * FROM `union_b` LIMIT 1

可能第一眼看到这个SQL的时候,会想到将会返回2条记录,但是,结果却是只返回1条记录。回忆UNION的语法,最后一个LIMIT 1其实是对UNION之后的结果集取1条记录。

二、关于ORDER BY

我的需求是这样的,`union_a`和`union_b`表按NUMBER字段升序排列,最后将2个结果集合并,你可能想到的SQL会是这个样子

  1. SELECT * FROM `union_a` ORDER BY `NUMBER`
  2. UNION ALL
  3. SELECT * FROM `union_b` ORDER BY `NUMBER`

前面也说过,这个SQL语句是有语法错误的,但是,可以尝试这样,使用()将每个子句包围

  1. (SELECT * FROM `union_a` ORDER BY `NUMBER`)
  2. UNION ALL
  3. (SELECT * FROM `union_b` ORDER BY `NUMBER`)

SQL语句顺利执行了,但是,结果却不是我们想要的。看前5条记录,`union_a`表中的数据并没有按照NUMBER字段升序排列

查阅MYSQL的官方文档,其中包含对UNION中使用ORDER BY的说明:

对UNION中的子句应用ORDER BY是无效的,ORDER BY只能用于UNION后的整个结果集。如果需要对子句应用ORDER BY,必须添加LIMIT。正确的SQL如下

  1. (SELECT * FROM `union_a`  ORDER BY `NUMBER` LIMIT 5)
  2. UNION ALL
  3. (SELECT * FROM `union_b` ORDER BY `NUMBER` LIMIT 5)

参考链接:

https://dev.mysql.com/doc/refman/5.7/en/union.html

http://stackoverflow.com/questions/6732661/incorrect-usage-of-union-and-order-by

MYSQL之union和order by分析([Err] 1221 - Incorrect usage of UNION and ORDER BY)的更多相关文章

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

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

  2. mysql Incorrect usage of UNION and ORDER BY 错误备忘

    出现这个错误的语句是酱紫的 select xxx from aaa order by xxx union all select yyy from bbb order by yyy 错误原因居然是,如果 ...

  3. MYSQL索引结构原理、性能分析与优化

    [转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...

  4. mysql优化(三)–explain分析sql语句执行效率

    mysql优化(三)–explain分析sql语句执行效率 mushu 发布于 11个月前 (06-04) 分类:Mysql 阅读(651) 评论(0) Explain命令在解决数据库性能上是第一推荐 ...

  5. 由浅入深探究mysql索引结构原理、性能分析与优化 转

    第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1. 简单介绍B-tree B+ tree树 2. MyisAM索引结构 3. Annode索引结构 4. MyisAM索引与Inno ...

  6. 由浅入深探究mysql索引结构原理、性能分析与优化

    摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1.简单介绍B-tree B+ tree树 2.MyisAM索引结构 3.Annode索引结构 4.MyisAM索引与Inno ...

  7. 【转】由浅入深探究mysql索引结构原理、性能分析与优化

    摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1.简单介绍B-tree B+ tree树 2.MyisAM索引结构 3.Annode索引结构 4.MyisAM索引与Inno ...

  8. [转载]由浅入深探究mysql索引结构原理、性能分析与优化

    第一部分:基础知识第二部分:MYISAM和INNODB索引结构1. 简单介绍B-tree B+ tree树 2. MyisAM索引结构 3. Annode索引结构 4. MyisAM索引与InnoDB ...

  9. 【MySQL】排序原理与案例分析

    前言 排序是数据库中的一个基本功能,MySQL也不例外.用户通过Order by语句即能达到将指定的结果集排序的目的,其实不仅仅是Order by语句,Group by语句,Distinct语句都会隐 ...

随机推荐

  1. Http中Content-Type的取值讲解

    一.Content-Type的取值 在Http请求中,我们每天都在使用Content-type来指定不同格式的请求信息(MediaType,即是Internet Media Type,互联网媒体类型: ...

  2. lambda表达式(2)

    转:http://www.cnblogs.com/kingmoon/archive/2011/05/03/2035696.html "Lambda表达式"是一个匿名函数,是一种高效 ...

  3. 关于 Python 程序的运行方面,有什么手段能提升性能?

    1.使用多进程,充分利用机器的多核性能2.对于性能影响较大的部分代码,可以使用 C 或 C++编写3.对于 IO 阻塞造成的性能影响,可以使用 IO 多路复用来解决4.尽量使用 Python 的内建函 ...

  4. vue v-model 的使用

    Vue的核心特性之一是双向绑定,vue的响应式原理是实现了数据->视图 v-bind只能实现数据的单向绑定 ,从M自动绑定到V 使用v-model 可以实现表单元素的双向绑定,且只能应用到表单元 ...

  5. node+mysql+express实现登录/注册/修改密码/删除用户 接口

    实现用户的注册.登录.修改密码.删除用户操作 用到的数据库:nodecms:表:user 目录结构: db目录下存放数据库操作语句: userSQL.js 用户有关的操作语句 router目录 接口路 ...

  6. iOS 应用配置及证书生成教程

    简介 首先你需要有一个苹果的开发者帐号,一台苹果电脑.点击查看苹果开发者账号注册流程 本教程需完成应用信息配置,包括如下两个基本配置: AppID Bundle ID 同时,生成 如下三个证书文件及对 ...

  7. 在eclipse中添加和删除项目

    一. 将JAVA文件夹导入Eclipse中的方法: 方法一:直接将java文件夹复制,然后粘贴到项目下: 方法二:(1)打开Eclipse,点击项目的空白处,现在import: (2)现在Existi ...

  8. C# 获取系统环境数据

    using System; using System.Data; using System.Text.RegularExpressions; using System.Threading; names ...

  9. python基础--3 列表

    #list类#li是list类的一个对象li=[11,22,33,22,44] #参数#在原来值最后进行整个作为元素追加 # li.append((11,22,33))#对列表本身进行操作,appen ...

  10. 读书笔记二、pandas之DataFrame

    注:DataFrame的构造方法与Series类似,只不过同时接受一条一维数据源,每一条都会成为单独的一列. 注意,返回的Series拥有原DataFrame 相同的索引,且其name属性也已经被相应 ...