SELECT ... UNION子句
SELECT ...UNION [ ALL | DISTINCT ]SELECT ... [UNION [ ALL | DISTINCT ] SELECT ...]
UNION
将来自多个SELECT
语句的结果合并到一个结果集中。结果集列名取自第一条SELECT
语句的列名。
在每个SELECT
语句的相应位置列出的所选列应具有相同的数据类型。(例如,第一个语句选择的第一列应与其他语句选择的第一列具有相同的类型。)如果对应SELECT
列的数据类型不匹配,则UNION
结果中各列的类型和长度取考虑所有SELECT
语句检索的值。例如,考虑以下内容:
mysql>SELECT REPEAT('a',1)UNION SELECT REPEAT('b',10); +--------------- + | REPEAT('a',1) | +--------------- + | a | | bbbbbbbbbb | +--------------- +
从MySQL 8.0.19开始,您还可以在可以使用等效语句的任何地方使用TABLE
语句或语句。假定表和被创建并填充,如下所示:VALUES
UNION
SELECT
t1
t2
CREATE TABLE t1(x INT, y INT);INSERT INTO t1VALUES ROW (4,-2),ROW (5,9);CREATE TABLE t2 (a INT, b INT);INSERT INTO t2VALUES ROW (1,2),ROW (3,4);
前面是这种情况,并且忽略以开头的查询的输出中的列名,VALUES
以下所有UNION
查询都会产生相同的结果:
SELECT *FROM t1UNION SELECT *FROM t2;TABLE t1UNION SELECT *FROM t2;VALUES ROW (4,-2),ROW (5,9)UNION SELECT *FROM t2;SELECT *FROM t1UNION TABLE t2;TABLE t1UNION TABLE t2;VALUES ROW (4,-2),ROW (5,9)UNION TABLE t2;SELECT *FROM t1UNION VALUES ROW (4,-2),ROW (5,9);TABLE t1UNION VALUES ROW (4,-2),ROW (5,9);VALUES ROW (4,-2),ROW (5,9)UNION VALUES ROW (4,-2),ROW (5,9);
您可以通过将VALUES
a左侧的换行SELECT
并使用别名来强制列名相同,如下所示:
SELECT *FROM (VALUES ROW (4,-2),ROW (5,9))AS t(x,y)UNION TABLE t2;SELECT *FROM (VALUES ROW (4,-2),ROW (5,9))AS t(x,y)UNION VALUES ROW (4,-2),ROW (5,9);
该SELECT
语句是普通的select语句,但具有以下限制:
HIGH_PRIORITY
不能与SELECT
组成部分的语句一起使用UNION
。如果为first指定它SELECT
,则它无效。如果为任何后续SELECT
语句指定它,则会导致语法错误。- 只有最后一条
SELECT
语句可以使用INTO
子句。但是,整个UNION
结果将被写入INTO
输出目标。 从MySQL 8.0.20开始,不推荐使用这两个
UNION
变体,INTO
并且在将来的MySQL版本中将不再支持它们:在查询表达式的结尾查询块中,使用
INTO
beforeFROM
会产生警告。例:...
UNION SELECT *INTO OUTFILE 'file_name'FROM table_name;在查询表达式的括号尾部,使用
INTO
(无论其相对于的位置FROM
)都会产生警告。例:...
UNION (SELECT *INTO OUTFILE 'file_name'FROM table_name);
弃用这些变体是因为它们令人困惑,就像它们从命名表而不是整个查询表达式(
UNION
)中收集信息一样。
默认情况下,从UNION
结果中删除重复的行。可选DISTINCT
关键字具有相同的效果,但使其显式。使用optional ALL
关键字时,不会发生重复行删除,并且结果包括所有SELECT
语句中的所有匹配行。
你可以混合UNION ALL
和UNION DISTINCT
在相同的查询。UNION
处理混合类型,以使DISTINCT
联合优先ALL
于其左侧的任何联合。甲DISTINCT
工会可以明确,通过使用来产生UNION DISTINCT
或隐式地通过使用UNION
没有以下DISTINCT
或ALL
关键字。
在MySQL 8.0.19和更高版本中,在联合中使用一个或多个语句时UNION ALL
,它们的UNION DISTINCT
工作方式相同TABLE
。
要应用ORDER BY
或LIMIT
应用于个人SELECT
,请将子句放在括在括号内的括号内SELECT
:
(SELECT aFROM t1WHERE a=10 AND B=1ORDER BY aLIMIT 10)UNION (SELECT aFROM t2WHERE a=11 AND B=2ORDER BY aLIMIT 10);
ORDER BY
对单个SELECT
语句的使用不暗示行在最终结果中出现的顺序,因为UNION
默认情况下会产生一组无序的行。因此,ORDER BY
在这种情况下,尽管它不一定会影响最终结果中这些行的顺序,但通常会与一起使用LIMIT
,以确定要检索的选定行的子集。如果没有出现在,它被优化掉,因为它不会有任何效果,反正。SELECT
UNION
ORDER BY
LIMIT
SELECT
要使用ORDER BY
or LIMIT
子句对整个UNION
结果进行排序或限制,请在各个SELECT
语句后加上括号,然后将ORDER BY
或LIMIT
放在最后一个语句之后。下面的示例使用两个子句:
(SELECT aFROM t1WHERE a=10 AND B=1)UNION (SELECT aFROM t2WHERE a=11 AND B=2)ORDER BY aLIMIT 10;
如前所述,不带括号的语句等效于一个带括号的语句。
从MySQL 8.0.19开始,请记住,不支持子句,可以使用ORDER BY
与所示相同的方式使用and LIMIT
with TABLE
联合。TABLE
WHERE
此类ORDER BY
不能使用包含表名(即tbl_name
。col_name
格式的名称)的列引用。而是在第一条SELECT
语句中提供列别名,并在中引用别名ORDER BY
。(或者,ORDER BY
使用其列位置引用该列。但是,不建议使用列位置。)
另外,如果要排序的列具有别名,则该ORDER BY
子句必须引用别名,而不是列名。以下语句中的第一个是允许的,但是第二个语句失败并显示Unknown column 'a' in 'order clause'
错误:
(SELECT aAS bFROM t)UNION (SELECT ...)ORDER BY b; (SELECT aAS bFROM t)UNION (SELECT ...)ORDER BY a;
要使UNION
结果中的行由一个接SELECT
一个的另一个行集合组成,请在每个行中选择一个额外的列SELECT
用作排序列,并ORDER BY
在最后一个列之后添加SELECT
:
(SELECT 1AS sort_col, col1a, col1b, ...FROM t1)UNION (SELECT 2, col2a, col2b, ...FROM t2)ORDER BY sort_col;
要在各个SELECT
结果中另外保持排序顺序,请在ORDER BY
子句中添加第二列:
(SELECT 1AS sort_col, col1a, col1b, ...FROM t1)UNION (SELECT 2, col2a, col2b, ...FROM t2)ORDER BY sort_col, col1a;
使用附加列还使您能够确定SELECT
每一行来自哪个行。额外的列也可以提供其他标识信息,例如指示表名的字符串。
UNION
在ORDER BY
子句中具有聚合函数的查询将被拒绝,并显示ER_AGGREGATE_ORDER_FOR_UNION
错误。例:
SELECT 1AS fooUNION SELECT 2ORDER BY MAX(1);