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語句。額外的列也可以更好的聲明返回結果每一行的信息,比如增加一個表名稱的列。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章