SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr] ...
[into_option]
[FROM table_references
[PARTITION partition_list]]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
[HAVING where_condition]
[WINDOW window_name AS (window_spec)
[, window_name AS (window_spec)] ...]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[into_option]
[FOR {UPDATE | SHARE}
[OF tbl_name [, tbl_name] ...]
[NOWAIT | SKIP LOCKED]
| LOCK IN SHARE MODE]
[into_option]
into_option: {
INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name] ...
}
SELECT 用於檢索從一個或多個資料表選取的資料列,並且可以包含 UNION 運算和子查詢。INTERSECT 和 EXCEPT 運算也受支援。 UNION、INTERSECT 和 EXCEPT 運算子將在本節稍後詳細說明。另請參閱 第 15.2.15 節「子查詢」。
SELECT 陳述式可以 WITH 子句開頭,以定義在 SELECT 內可存取的共用資料表運算式。請參閱 第 15.2.20 節「WITH(共用資料表運算式)」。
SELECT 陳述式最常用的子句如下:
每個
select_expr都表示您要檢索的欄位。必須至少有一個select_expr。table_references表示要從中檢索資料列的資料表。其語法在 第 15.2.13.2 節「JOIN 子句」中說明。SELECT支援使用PARTITION子句來明確選取分割區,該子句在table_reference中的資料表名稱後接分割區或子分割區(或兩者)的清單(請參閱 第 15.2.13.2 節「JOIN 子句」)。在這種情況下,只會從列出的分割區中選取資料列,並且會忽略資料表的任何其他分割區。如需詳細資訊和範例,請參閱 第 26.5 節「分割區選取」。如果給定
WHERE子句,則它會表示資料列必須滿足才能被選取的條件。對於要選取的每個資料列,where_condition是評估為 true 的運算式。如果沒有WHERE子句,則陳述式會選取所有資料列。在
WHERE運算式中,您可以使用 MySQL 支援的任何函數和運算子,但彙總(群組)函數除外。請參閱 第 11.5 節「運算式」和 第 14 章函數和運算子。
SELECT 也可用於檢索在不參考任何資料表的情況下計算的資料列。
例如:
mysql> SELECT 1 + 1;
-> 2
在未參考任何資料表的情況下,您可以使用 DUAL 作為虛擬資料表名稱。
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
DUAL 純粹是為了方便需要所有 SELECT 陳述式都應具有 FROM 和其他子句的人們。MySQL 可能會忽略這些子句。如果未參考任何資料表,則 MySQL 不需要 FROM DUAL。
一般來說,使用的子句必須完全按照語法說明中顯示的順序給定。例如,HAVING 子句必須位於任何 GROUP BY 子句之後,以及任何 ORDER BY 子句之前。如果存在 INTO 子句,則它可以在語法說明中指示的任何位置出現,但在給定的陳述式中只能出現一次,而不是在多個位置出現。如需有關 INTO 的詳細資訊,請參閱 第 15.2.13.1 節「SELECT ... INTO 陳述式」。
select_expr 術語清單包含選取清單,它表示要檢索哪些欄位。術語指定欄位或運算式,或可以使用 * 縮寫。
僅由單一不合格
*組成的選取清單可以用作縮寫,以選取所有資料表的所有欄位。SELECT * FROM t1 INNER JOIN t2 ...可用作合格的縮寫,以選取指定資料表的所有欄位。tbl_name.*SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ...如果資料表有隱藏欄位,則
*和不會包含這些欄位。若要包含這些欄位,必須明確參考隱藏欄位。tbl_name.*在選取清單中將不合格的
*與其他項目一起使用可能會產生剖析錯誤。例如:SELECT id, * FROM t1若要避免此問題,請使用合格的
參考。tbl_name.*SELECT id, t1.* FROM t1在選取清單中,針對每個資料表使用合格的
參考。tbl_name.*SELECT AVG(score), t1.* FROM t1 ...
以下清單提供有關其他 SELECT 子句的其他資訊:
可以使用
AS為alias_nameselect_expr指定別名。別名會用作運算式的欄位名稱,並可用於GROUP BY、ORDER BY或HAVING子句。例如:SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;使用識別碼為
select_expr設定別名時,AS關鍵字是選用的。先前的範例可以寫成這樣:SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name;但是,因為
AS是選用的,所以如果您忘記兩個select_expr運算式之間的逗號,就會發生細微的問題:MySQL 會將第二個運算式解譯為別名名稱。例如,在以下陳述式中,columnb會被視為別名名稱:SELECT columna columnb FROM mytable;因此,在指定欄位別名時,最好養成明確使用
AS的習慣。在
WHERE子句中參考欄位別名是不可允許的,因為執行WHERE子句時可能尚未決定欄位值。請參閱 第 B.3.4.4 節「欄位別名的問題」。FROM子句表示要從中檢索資料列的資料表。如果您命名多個資料表,則表示您要執行聯結。如需有關聯結語法的資訊,請參閱 第 15.2.13.2 節「JOIN 子句」。對於指定的每個資料表,您可以選擇性地指定別名。table_referencestbl_name [[AS] alias] [index_hint]使用索引提示會為最佳化工具提供有關如何在查詢處理期間選擇索引的資訊。如需有關指定這些提示的語法描述,請參閱 第 10.9.4 節「索引提示」。
您可以使用
SET max_seeks_for_key=作為強制 MySQL 優先選擇索引掃描而非資料表掃描的替代方法。請參閱 第 7.1.8 節「伺服器系統變數」。value您可以將預設資料庫中的資料表稱為
tbl_name,或稱為db_name.tbl_name來明確指定資料庫。您可以將欄位稱為col_name、tbl_name.col_name或db_name.tbl_name.col_name。除非參考具有歧義,否則您不需要為欄位參考指定tbl_name或db_name.tbl_name字首。請參閱 第 11.2.2 節「識別碼限定詞」,以取得需要更明確欄位參考形式的歧義範例。可以使用
或tbl_nameASalias_nametbl_name alias_name為資料表參考設定別名。這些陳述式是等效的:SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name; SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;使用欄位名稱、欄位別名或欄位位置,可以在
ORDER BY和GROUP BY子句中參考選取用於輸出的欄位。欄位位置是整數,從 1 開始:SELECT college, region, seed FROM tournament ORDER BY region, seed; SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; SELECT college, region, seed FROM tournament ORDER BY 2, 3;若要以相反的順序排序,請將
DESC(遞減)關鍵字新增到ORDER BY子句中您要依之排序的欄位名稱。預設為遞增順序;可以使用ASC關鍵字明確指定遞增順序。如果
ORDER BY出現在加上括號的查詢運算式中,且也套用於外部查詢中,則結果是未定義的,並且可能會在 MySQL 的未來版本中變更。不建議使用欄位位置,因為語法已從 SQL 標準中移除。
當您使用
ORDER BY或GROUP BY來排序SELECT中的欄位時,伺服器只會使用max_sort_length系統變數所指定的初始位元組數來排序值。MySQL 擴展了
GROUP BY的使用,允許選取未在GROUP BY子句中提及的欄位。如果您從查詢中得到的結果與預期不符,請閱讀 第 14.19 節「彙總函式」中關於GROUP BY的說明。如同
WHERE子句,HAVING子句也指定選取條件。WHERE子句指定選取清單中欄位的條件,但不能參照彙總函式。HAVING子句指定群組的條件,通常由GROUP BY子句形成。查詢結果僅包含滿足HAVING條件的群組。(如果沒有GROUP BY,則所有列都隱式形成單一群組。)HAVING子句幾乎是在最後才應用,僅在項目傳送到客戶端之前,且沒有任何最佳化。(LIMIT是在HAVING之後應用。)SQL 標準要求
HAVING必須僅參照GROUP BY子句中的欄位或彙總函式中使用的欄位。但是,MySQL 支援此行為的擴展,並允許HAVING參照SELECT清單中的欄位以及外部子查詢中的欄位。如果
HAVING子句參照的欄位不明確,則會發生警告。在以下陳述式中,col2不明確,因為它同時用作別名和欄位名稱SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;會優先考量標準 SQL 行為,因此如果
HAVING欄位名稱同時在GROUP BY和選取欄位清單中作為別名欄位使用,則會優先考量GROUP BY欄位中的欄位。請勿將應該在
WHERE子句中的項目使用HAVING。例如,不要寫成以下這樣SELECT col_name FROM tbl_name HAVING col_name > 0;請改寫成這樣
SELECT col_name FROM tbl_name WHERE col_name > 0;HAVING子句可以參照彙總函式,而WHERE子句則不能SELECT user, MAX(salary) FROM users GROUP BY user HAVING MAX(salary) > 10;(這在某些舊版的 MySQL 中無法運作。)
MySQL 允許重複的欄位名稱。也就是說,可以有多個名稱相同的
select_expr。這是標準 SQL 的擴展。由於 MySQL 也允許GROUP BY和HAVING參照select_expr值,這可能會導致不明確的情況SELECT 12 AS a, a FROM t GROUP BY a;在該陳述式中,兩個欄位都有名稱
a。為了確保使用正確的欄位進行分組,請為每個select_expr使用不同的名稱。如果存在
WINDOW子句,則會定義可由視窗函式參照的具名視窗。如需詳細資訊,請參閱第 14.20.4 節「具名視窗」。MySQL 會先在
select_expr值中搜尋,然後在FROM子句的表格欄位中搜尋,以此來解析ORDER BY子句中未限定的欄位或別名參照。對於GROUP BY或HAVING子句,它會先搜尋FROM子句,然後再搜尋select_expr值。(對於GROUP BY和HAVING,這與 MySQL 5.0 之前使用與ORDER BY相同規則的行為不同。)LIMIT子句可用於限制SELECT陳述式傳回的列數。LIMIT接受一個或兩個數值引數,它們都必須是非負整數常數,但以下例外在預備陳述式中,可以使用
?預留位置標記來指定LIMIT參數。在儲存程式中,可以使用整數值常式參數或局部變數來指定
LIMIT參數。
使用兩個引數時,第一個引數指定要傳回的第一列的位移量,第二個引數指定要傳回的最大列數。初始列的位移量為 0(而非 1)
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15若要從特定位移量開始擷取到結果集結尾的所有列,您可以使用較大的數值作為第二個參數。此陳述式會擷取從第 96 列到最後一列的所有列
SELECT * FROM tbl LIMIT 95,18446744073709551615;使用一個引數時,該值指定從結果集開頭傳回的列數
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows換句話說,
LIMIT等同於row_countLIMIT 0,。row_count對於預備陳述式,您可以使用預留位置。以下陳述式會從
tbl表格傳回一列SET @a=1; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?'; EXECUTE STMT USING @a;以下陳述式會從
tbl表格傳回第二列到第六列SET @skip=1; SET @numrows=5; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?'; EXECUTE STMT USING @skip, @numrows;為了與 PostgreSQL 相容,MySQL 也支援
LIMIT語法。row_countOFFSEToffset如果
LIMIT出現在括號內的查詢運算式中,並且也應用於外部查詢中,則結果將是未定義的,並且可能會在未來的 MySQL 版本中變更。SELECT ... INTO形式的SELECT可讓查詢結果寫入檔案或儲存在變數中。如需詳細資訊,請參閱第 15.2.13.1 節「SELECT ... INTO 陳述式」。如果您使用
FOR UPDATE並搭配使用頁面或列鎖定的儲存引擎,則查詢所檢查的列將會寫入鎖定,直到目前交易結束為止。您不能在陳述式中使用
FOR UPDATE作為SELECT的一部分,例如CREATE TABLE。(如果您嘗試這麼做,則會拒絕此陳述式並出現錯誤 在建立 'new_tableSELECT ... FROMold_table...new_table' 時,無法更新表格 'old_table'。)FOR SHARE和LOCK IN SHARE MODE會設定共用鎖定,允許其他交易讀取所檢查的列,但不允許更新或刪除它們。FOR SHARE和LOCK IN SHARE MODE是等效的。但是,如同FOR UPDATE,FOR SHARE支援NOWAIT、SKIP LOCKED和OF選項。tbl_nameFOR SHARE是LOCK IN SHARE MODE的替代方案,但為了回溯相容性,LOCK IN SHARE MODE仍然可用。NOWAIT會導致FOR UPDATE或FOR SHARE查詢立即執行,如果由於另一個交易持有的鎖定而無法取得列鎖定,則會傳回錯誤。SKIP LOCKED會導致FOR UPDATE或FOR SHARE查詢立即執行,並從結果集中排除由另一個交易鎖定的列。NOWAIT和SKIP LOCKED選項對於以陳述式為基礎的複寫是不安全的。注意跳過鎖定列的查詢會傳回不一致的資料檢視。
SKIP LOCKED因此不適用於一般交易工作。但是,當多個工作階段存取類似佇列的相同表格時,可以使用它來避免鎖定爭用。OF會將tbl_nameFOR UPDATE和FOR SHARE查詢套用到具名的表格。例如SELECT * FROM t1, t2 FOR SHARE OF t1 FOR UPDATE OF t2;省略
OF時,會鎖定查詢區塊所參照的所有表格。因此,將鎖定子句與另一個鎖定子句組合使用而不使用tbl_nameOF會傳回錯誤。在多個鎖定子句中指定相同表格會傳回錯誤。如果在tbl_nameSELECT陳述式中將別名指定為表格名稱,則鎖定子句只能使用別名。如果SELECT陳述式未明確指定別名,則鎖定子句只能指定實際的表格名稱。如需關於
FOR UPDATE和FOR SHARE的詳細資訊,請參閱第 17.7.2.4 節「鎖定讀取」。如需關於NOWAIT和SKIP LOCKED選項的其他資訊,請參閱使用 NOWAIT 和 SKIP LOCKED 進行鎖定讀取並行。
在 SELECT 關鍵字之後,您可以使用許多會影響陳述式操作的修飾詞。HIGH_PRIORITY、STRAIGHT_JOIN 和以 SQL_ 開頭的修飾詞是 MySQL 對標準 SQL 的擴展。
ALL和DISTINCT修飾詞指定是否應傳回重複的列。ALL(預設值)指定應傳回所有符合的列,包括重複的列。DISTINCT指定從結果集中移除重複的列。指定兩個修飾詞都是錯誤。DISTINCTROW是DISTINCT的同義詞。DISTINCT可以與也使用WITH ROLLUP的查詢一起使用。HIGH_PRIORITY賦予SELECT比更新表格的陳述式更高的優先順序。您應該僅將此用於非常快且必須立即完成的查詢。當表格被鎖定以進行讀取時,即使有更新陳述式正在等待表格空閒,發出的SELECT HIGH_PRIORITY查詢也會執行。這只會影響僅使用表格層級鎖定的儲存引擎(例如MyISAM、MEMORY和MERGE)。HIGH_PRIORITY不能與屬於UNION的SELECT陳述式一起使用。STRAIGHT_JOIN強制最佳化工具依照FROM子句中列出的順序聯結資料表。如果最佳化工具以非最佳順序聯結資料表,您可以使用此選項來加速查詢。STRAIGHT_JOIN也可以在table_references清單中使用。請參閱第 15.2.13.2 節「JOIN 子句」。STRAIGHT_JOIN不適用於任何最佳化工具視為const或system的資料表。這類資料表會產生單一列,在查詢執行最佳化階段讀取,且在查詢執行繼續之前,其欄位的參照會被替換為適當的欄位值。這些資料表會優先顯示在EXPLAIN所顯示的查詢計畫中。請參閱第 10.8.1 節「使用 EXPLAIN 最佳化查詢」。此例外情況可能不適用於外部聯結的 NULL 補全側使用的const或system資料表(即LEFT JOIN的右側資料表或RIGHT JOIN的左側資料表)。SQL_BIG_RESULT或SQL_SMALL_RESULT可以與GROUP BY或DISTINCT一起使用,以告知最佳化工具結果集分別具有許多列或很少列。對於SQL_BIG_RESULT,如果已建立磁碟型暫存資料表,MySQL 會直接使用,並且偏好排序而不是在GROUP BY元素上使用帶有索引鍵的暫存資料表。對於SQL_SMALL_RESULT,MySQL 會使用記憶體中的暫存資料表來儲存結果資料表,而不是使用排序。通常不需要這樣做。SQL_BUFFER_RESULT強制將結果放入暫存資料表。這有助於 MySQL 提早釋放資料表鎖定,並有助於將結果集傳送給用戶端需要很長時間的情況。此修飾符只能用於最上層的SELECT陳述式,不能用於子查詢或後接UNION的陳述式。SQL_CALC_FOUND_ROWS會告知 MySQL 計算結果集中將會有多少列,而不考慮任何LIMIT子句。然後可以使用SELECT FOUND_ROWS()擷取列數。請參閱第 14.15 節「資訊函數」。注意SQL_CALC_FOUND_ROWS查詢修飾符和隨附的FOUND_ROWS()函數已過時;預計在未來的 MySQL 版本中會將其移除。有關替代策略的資訊,請參閱FOUND_ROWS()的說明。在 MySQL 9.0 之前,
SQL_CACHE和SQL_NO_CACHE修飾符與查詢快取一起使用。查詢快取已在 MySQL 9.0 中移除。SQL_CACHE修飾符也一併移除。SQL_NO_CACHE已過時,並且沒有任何作用;預計在未來的 MySQL 版本中將會移除。