MySQL学习(五) UNION与UNION ALL

UNION用于把来自许多SELECT语句的结果组合到一个结果集合中,也叫联合查询。

复制代码 代码如下:

   最近也是在写项目中碰到的这个问题,需要将两个SELECT查询结果组合起来进行分组排序,想到了用union方法,用TP的union操作根本无法完成复杂的union操作,于是搜罗了一下,先说一下union的用法,在说一下TP中如何实现复杂的union操作。

SELECT ...
UNION [ALL | DISTINCT]
SELECT ...
[UNION [ALL | DISTINCT]
SELECT ...]

SELECT …
UNION [ALL | DISTINCT]
SELECT …
[UNION [ALL | DISTINCT]
SELECT …]
SELECT … UNION [ALL | DISTINCT] SELECT … [UNION [ALL |
DISTINCT] SELECT …]

  一、UNION 用法

在多个 SELECT 语句中,第一个 SELECT
语句中被使用的字段名称将被用于结果的字段名称。

UNION 用于把来自许多SELECT语句的结果组合到一个结果集合中。
(如果你要将多个表的查询结果进行合并输出比如说
群组消息跟个人消息表是分离的但是想一起提取出来并显示的话就可以如此处理。通过MySQLUNION联合查询出来即可)
列于每个SELECT语句的对应位置的被选择的列应具有相同的类型(前提条件是两个SELECT出来的列类型要保持一样的才行!)。(例如,被第一
个语句选择的第一列应和被其它语句选择的第一列具有相同的类型。)在第一个SELECT语句中被使用的列名称也被用于结果的列名称。
SELECT语句为常规的选择语句,但是受到如下的限定:
只有最后一个SELECT语句可以使用INTO OUTFILE。
HIGH_PRIORITY不能与作为UNION一部分的SELECT语句同时使用。如果您对第一个
SELECT指定了HIGH_PRIORITY,则不会起作用。如果您对其它后续的SELECT语句指定HIGH_PRIORITY,则会产生语法错
误。
如果您对UNION不使用关键词ALL,则所有返回的行都是唯一的,如同您已经对整个结果集合使用了DISTINCT。如果您指定了ALL,您会从
所有用过的SELECT语句中得到所有匹配的行。
DISTINCT关键词是一个自选词,不起任何作用,但是根据SQL标准的要求,在语法中允许采用。(在MySQL中,DISTINCT代表一个共
用体的默认工作性质。)
您可以在同一查询中混合UNION ALL和UNION
DISTINCT。被混合的UNION类型按照这样的方式对待,即DISTICT共用体覆盖位于其左边的所有ALL共用体。DISTINCT共用体可以使
用UNION
DISTINCT明确地生成,或使用UNION(后面不加DISTINCT或ALL关键词)隐含地生成。
如果您想使用ORDER
BY或LIMIT子句来对全部UNION结果进行分类或限制,则应对单个地SELECT语句加圆括号,并把ORDER
BY或LIMIT放到最后一个的后面。以下例子同时使用了这两个子句:
代码
(SELECT a FROM tbl_name WHERE a=10 AND B=1)UNION(SELECT a FROM
tbl_name WHERE a=11 AND B=2)ORDER BY a LIMIT 10;
(如果想要实现分页的话可以这样处理
将两个查询的结果集当作是一个大的结果集处理然后再对此大的结果集进行LIMIT处理即可实现!)好好好
~!
(SELECT a FROM tbl_name WHERE a=10 AND B=1)MySQLUNION(SELECT a FROM
tbl_name WHERE a=11 AND B=2)ORDER BY a LIMIT 10;
这种ORDER
BY不能使用包括表名称(也就是,采用tbl_name.col_name格式的名称)列引用。可以在第一个SELECT语句中提供一个列别名,并在
ORDER BY中参阅别名,或使用列位置在ORDER
BY中参阅列。(首选采用别名,因为不建议使用列位置。)
另外,如果带分类的一列有别名,则ORDER
BY子句必须引用别名,而不能引用列名称。以下语句中的第一个语句必须运行,但是第二个会运行失败,出现在’order
clause’中有未知列’a’的错误:
代码

  一 UNION语法

当使用 UNION 时,MySQL 会把结果集中重复的记录删掉,而使用 UNION ALL
,MySQL 会把所有的记录返回,且效率高于 UNION。

复制代码 代码如下:

  SELECT …

数据准备

(SELECT a AS b FROM t) UNION (SELECT …) ORDER BY b;
(SELECT a AS b FROM t) UNION (SELECT …) ORDER BY a;
To apply ORDER BY or LIMIT to an individual SELECT,
place the clause inside the parentheses that enclose the SELECT:
(SELECT a AS b FROM t) UNION (SELECT …) ORDER BY b;
(SELECT a AS b FROM t) UNION (SELECT …) ORDER BY a;
To apply ORDER BY or LIMIT to an individual SELECT,
place the clause inside the parentheses that enclose the SELECT:

  UNION[ALL | DISTINCT]

student表

为了对单个SELECT使用ORDER
BY或LIMIT,应把子句放入圆括号中。圆括号包含了SELECT:
代码

  SELECT …

-- ----------------------------
-- Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `age` tinyint(4) DEFAULT NULL,
  `classId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', 's1', '20', '1');
INSERT INTO `student` VALUES ('2', 's2', '22', '1');
INSERT INTO `student` VALUES ('3', 's3', '22', '2');
INSERT INTO `student` VALUES ('4', 's4', '25', '2');

复制代码 代码如下:

  [UNION [ALL | DISTINCT]

teacher表

(SELECT a FROM tbl_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION(SELECT a FROM tbl_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
(SELECT a FROM tbl_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION(SELECT a FROM tbl_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

  SELECT …]

-- ----------------------------
-- Table structure for `teacher`
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `age` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES ('1', 't1', '36');
INSERT INTO `teacher` VALUES ('2', 't2', '33');
INSERT INTO `teacher` VALUES ('3', 's3', '22');

二 实例扩展
MySQLunion可以对同一个表的两次查询联合起来. 这样做的益处也非常明显,
比如在blog应用中, 可以利用一条sql语句实现置顶blog和普通blog的分页显示.
代码

  UNION用于把来自许多SELECT语句的结果组合到一个结果集合中。

查询数据如下

复制代码 代码如下:

  列于每个SELECT语句的对应位置的被选择的列应具有相同的类型。(例如,被第一个语句选择的第一列应和被其它语句选择的第一列具有相同的类型。www.111cn.net)在第一个SELECT语句中被使用的列名称也被用于结果的列名称。

mysql> SELECT * FROM student;
+----+------+-----+---------+
| id | name | age | classId |
+----+------+-----+---------+
|  1 | s1   |  20 |       1 |
|  2 | s2   |  22 |       1 |
|  3 | s3   |  22 |       2 |
|  4 | s4   |  25 |       2 |
+----+------+-----+---------+
4 rows in set

mysql> SELECT * FROM teacher;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | t1   |  36 |
|  2 | t2   |  33 |
|  3 | s3   |  22 |
+----+------+-----+
3 rows in set

(
SELECT *
FROM `blog`
WHERE top=1
ORDER BY created DESC
)
UNION (
SELECT *
FROM `blog`
WHERE top = 0
ORDER BY created DESC
) LIMIT 2 , 3

  SELECT语句为常规的选择语句,但是受到如下的限定:

使用 UNION的结果

以上的相关内容就是对MySQLunion语法的介绍,望你能有所收获。

  ·只有最后一个SELECT语句可以使用INTO OUTFILE。

mysql> SELECT id, name, age FROM student
    -> UNION  -- 与UNION DISTINCT相同
    -> SELECT id, name, age FROM teacher;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | s1   |  20 |
|  2 | s2   |  22 |
|  3 | s3   |  22 |
|  4 | s4   |  25 |
|  1 | t1   |  36 |
|  2 | t2   |  33 |
+----+------+-----+
6 rows in set

您可能感兴趣的文章:

  • Mysql联合查询UNION和UNION
    ALL的使用介绍
  • MySQL中union和order
    by同时使用的实现方法
  • Mysql联合查询UNION和Order
    by同时使用报错问题的解决办法
  • 浅析mysql union和union
    all
  • MySQL中使用表别名与字段别名的基本教程
  • 关于sql和mysql对于别名不能调用的一些理解
  • MySQL笔记之别名的使用
  • MySQL
    Union合并查询数据及表别名、字段别名用法分析

  ·HIGH_PRIORITY不能与作为UNION一部分的SELECT语句同时使用。如果您对第一个
SELECT指定了HIGH_PRIORITY,则不会起作用。如果您对其它后续的SELECT语句指定了HIGH_PRIORITY,则会产生语法错误。

使用 UNION ALL的结果

  如果您对UNION不使用关键词ALL,则所有返回的行都是唯一的,如同您已经对整个结果集合使用了DISTINCT。如果您指定了ALL,您会从所有用过的SELECT语句中得到所有匹配的行。

mysql> SELECT id, name, age FROM student
    -> UNION ALL
    -> SELECT id, name, age FROM teacher;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | s1   |  20 |
|  2 | s2   |  22 |
|  3 | s3   |  22 |
|  4 | s4   |  25 |
|  1 | t1   |  36 |
|  2 | t2   |  33 |
|  3 | s3   |  22 |
+----+------+-----+
7 rows in set

  DISTINCT关键词是一个自选词,不起任何作用,但是根据SQL标准的要求,在语法中允许采用。(在MySQL中,DISTINCT代表一个共用体的默认工作性质。)

其实联合查询跟字段的类型无关,只要求每个SELECT查询的字段数一样,能对应即可,如

  您可以在同一查询中混合UNION ALL和UNION
DISTINCT。被混合的UNION类型按照这样的方式对待,即DISTINCT共用体覆盖位于其左边的所有ALL共用体。DISTINCT共用体可以使用UNION
DISTINCT明确地生成,或使用UNION(后面不加DISTINCT或ALL关键词)隐含地生成。

mysql> SELECT id, name, age FROM student -- 这里可以看出第一个SELECT语句中的字段名称被用作最后结果的字段名
    -> UNION
    -> SELECT age, name, id FROM teacher;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | s1   |  20 |
|  2 | s2   |  22 |
|  3 | s3   |  22 |
|  4 | s4   |  25 |
| 36 | t1   |   1 |
| 33 | t2   |   2 |
| 22 | s3   |   3 |
+----+------+-----+
7 rows in set

  如果您想使用ORDER
BY或LIMIT子句来对全部UNION结果进行分类或限制,则应对单个地SELECT语句加圆括号,并把ORDER
BY或LIMIT放到最后一个的后面。以下例子同时使用了这两个子句:

在联合查询中,当使用ORDER
BY的时候,需要对SELECT语句添加括号,并且与LIMIT结合使用才生效,如

 代码如下

mysql> (SELECT classId, id, name, age FROM student WHERE classId = 1 ORDER BY age DESC)
    -> UNION
    -> (SELECT classId, id, name, age FROM student WHERE classId = 2 ORDER BY age);
+---------+----+------+-----+
| classId | id | name | age |
+---------+----+------+-----+
|       1 |  1 | s1   |  20 |
|       1 |  2 | s2   |  22 |
|       2 |  3 | s3   |  22 |
|       2 |  4 | s4   |  25 |
+---------+----+------+-----+
4 rows in set

 

此时classId为1的学生并没有按照年龄进行降序,结合LIMIT后

(SELECT a FROM tbl_name WHERE a=10 AND B=1)UNION(SELECT a FROM
tbl_name WHERE a=11 AND B=2)ORDER BY a LIMIT 10;   

mysql> (SELECT classId, id, name, age FROM student WHERE classId = 1 ORDER BY age DESC LIMIT 2)
    -> UNION
    -> (SELECT classId, id, name, age FROM student WHERE classId = 2 ORDER BY age);
+---------+----+------+-----+
| classId | id | name | age |
+---------+----+------+-----+
|       1 |  2 | s2   |  22 |
|       1 |  1 | s1   |  20 |
|       2 |  3 | s3   |  22 |
|       2 |  4 | s4   |  25 |
+---------+----+------+-----+
4 rows in set

 (SELECT a FROM tbl_name WHERE a=10 AND B=1)UNION(SELECT a FROM
tbl_name WHERE a=11 AND B=2)ORDER BY a LIMIT 10;

 

  这种ORDER
BY不能使用包括表名称(也就是,采用tbl_name.col_name格式的名称)列引用。可以在第一个SELECT语句中提供一个列别名,并在ORDER
BY中参阅别名,或使用列位置在ORDER
BY中参阅列。(首选采用别名,因为不建议使用列位置。)

  另外,如果带分类的一列有别名,则ORDER BY
www.111cn.nEt子句必须引用别名,而不能引用列名称。以下语句中的第一个语句必须运行,但是第二个会运行失败,出现在’order
clause’中有未知列’a’的错误:

 代码如下