UNION 语法

13.2.9.3 UNION 语法

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

UNION 作用是将多个select语句的结果整合到一个结果中返回。

以第一个select语句的列名称作为返回结果的列名称,每个select语句对应列返回的数据类型应该一致。

如果数据类型不匹配,union结果会从所有的select语句中推测返回列的类型和长度。比如:

mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10);
+---------------+
| REPEAT('a',1) |
+---------------+
| a             |
| bbbbbbbbbb    |
+---------------+

这是一个常见的select语句,但是有一下限制:
* 只有最后一个select语句能够使用INTO OUTFILE(尽管是将整个union结果写入到文件中)。
* HIGH_PRIORITY 语句不能在union中使用,如果你在第一个select语句中使用 HIGH_PRIORITY,实际上并不会起效。如果放到其他select语句中,则会报语法错误。

union默认会对返回结果去重,等同于union distinct。如果使用ALL关键字,将不会去重。

你可以同时在同一个查询语句中使用UNION ALL 和 UNION DISTINCT,UNION DISTINCT语句会覆盖出现在他前面的UNION ALL语句。

如果想对其中一个select语句使用ORDER BY 或 LIMIT,你需要将这个select语句用括号括起来:

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

尽管上面的例子可以使用,但ORDER BY的结果并不会影响最终的返回结果,因为UNION产生的结果是一个无序集合。所以典型的使用ORDER BY场景是和LIMIT一块使用的,用于只取一部分数据。如果ORDER BY没有和LIMIT一块使用,执行时优化器会去掉ORDER BY语句。

如果相对整个union结果使用ORDER BY 或 LIMIT,需要将每一个select语句括起来,最后加上ORDER BY 或 LIMIT:

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

如果有一个select语句没有被括起来,等同于对单个语句使用ORDER BY 或 LIMIT。

这种方式的ORDER BY使用列,不用表明限定(tbl_name.col_name)。你需要对第一个select的列定义别名,然后order by中使用别名排序。(也可以order by 字段出现的位置,这种方式不建议使用)

如果一个要排序的列定义的别名,那么ORDER BY只能使用别名,不能使用列名称。下面的第一个列子可以执行,但是第二个会报“Unknown column ‘a’ in ‘order clause’”的错误:

(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b;
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;

如果想让返回结果中,后一个select的结果都在前一个select结构的后面,可以增加一个排序列,并按次列排序即可:

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col;

如果想进一步对select里面的结果也有序,可以再增加一个排序列:

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col, col1a;

使用附加列可以让你知道返回结果来源于那个select语句。额外的列也可以更好的声明返回结果每一行的信息,比如增加一个表名称的列。

猜你喜欢

转载自blog.csdn.net/jeffrey_li/article/details/80454776