我在一个业务中采用了按月的分表策略,当查询的条件跨月的时候,使用了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. 编程字体Source Code Pro 免费下载

    对于程序员来说,好的字体应该满足的基本条件: 字母和数字易于分辨,如: 英文字母o 和 阿拉伯数字 0 ,或者 英文字母 l 和 阿拉伯数字 1 ,两个单引号 '' 和双引号 ”. 字体等宽,保持对齐 ...

  2. vuer-cli 安装笔记

    电脑上装 的软件全卸载了.需要 重装 .整理了一下vue-cli脚手架搭建 1 先下载git 2 再下载node 3安装淘宝镜像 (https://npm.taobao.org/) 4 安装webpa ...

  3. 前端 CSS的选择器 伪类选择器

    伪类选择器 常用的几种伪类选择器. 伪类选择器一般会用在超链接a标签中 没有访问的超链接a标签样式: a:link { color: blue; } <!DOCTYPE html> < ...

  4. Spring Boot 集成 Ehcache 缓存,三步搞定!

    作者:谭朝红 www.ramostear.com/articles/spring_boot_ehcache.html 本次内容主要介绍基于Ehcache 3.0来快速实现Spring Boot应用程序 ...

  5. 《剑指offer》面试题17 合并两个排序的链表 Java版

    我的方法:新初始化一个链表头,比较两个链表当前节点的大小,然后连接到该链表中.遍历两个链表直到null为止. public ListNode merge(ListNode first, ListNod ...

  6. SpringDataJPA使用

    一.简介 SpringDataJpa是 JPA规范的一个很好的实现,简化了开发的复杂度,极大提升了开发的效率.SpringDataJpa通过 Repository接口及子接口可以很方便的实现持久化操作 ...

  7. socket服务器

    Python 3.x,已经改名为socketserver:Python 2. #coding=utf-8 #1.必须自己创建一个请求处理类,并且这个类要继承BaseRequesHandler,并且还要 ...

  8. menustrip

    在对应菜单上点击鼠标右键,插入,SEPARATOR 就可以了,然后可以选中拖动位置.

  9. win32 socket 编程(六)——UDP

    基于 UDP 无连接的 socket 编程 一.服务器端操作流程 1.1加载套接字库(WSAStartup) 1.2 创建套接字  (socket) 1.3将创建的套接字绑定到一个本地地址和端口上   ...

  10. SAAS多租户数据逻辑隔离

    基于Mybatis 的SAAS应用多租户数据逻辑隔离 package com.opencloud.common.interceptor;import org.apache.commons.lang3. ...