msyql的select語法

13.2.7. SELECT語法

13.2.7.1. JOIN語法
13.2.7.2. UNION語法


SELECT

[ALL | DISTINCT | DISTINCTROW ]

[HIGH_PRIORITY]

[STRAIGHT_JOIN]

[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]

[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]

select_expr, ...

[INTO OUTFILE 'file_name' export_options

| INTO DUMPFILE 'file_name']

[FROM table_references

[WHERE where_definition]

[GROUP BY {col_name | expr | position}

[ASC | DESC], ... [WITH ROLLUP]]

[HAVING where_definition]

[ORDER BY {col_name | expr | position}

[ASC | DESC] , ...]

[LIMIT {[offset,] row_count | row_count OFFSET offset}]

[PROCEDURE procedure_name(argument_list)]

[FOR UPDATE | LOCK IN SHARE MODE]]

SELECT用於恢復從一個或多個表中選擇的行,並可以加入UNION語句和子查詢。請參見13.2.7.2節,“UNION語法
”和13.2.8節,“Subquery語法”。

· 每個select_expr都指示一個您想要恢復的列。

· table_references指示行從哪個表或哪些表中被恢復。在13.2.7.1節,“JOIN語法”中對該語法進行了說明。

· where_definition包括關鍵詞WHERE,後面接一個表達式。該表達式指示被選擇的行必須滿足的條件。

有的行在計算時未引用任何表。SELECT也可以用於恢復這類行。

舉例說明:

mysql> SELECT 1 + 1;

-> 2

所有被使用的子句必須按語法說明中顯示的順序嚴格地排序。例如,一個HAVING子句必須位於GROUP BY子句之後,並位於ORDER BY子句之前。

· 使用AS alias_name可以爲select_expr給定一個別名。此別名用作表達式的列名,可以用於GROUP BY、ORDER BY或HAVING子句。例如:

· mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name

· -> FROM mytable ORDER BY full_name;

在爲select_expr給定別名時,AS關鍵詞是自選的。前面的例子可以這樣編寫:

mysql> SELECT CONCAT(last_name,', ',first_name) full_name

-> FROM mytable ORDER BY full_name;

因爲AS是自選的,如果您忘記在兩個select_expr表達式之間加逗號,則會出現一個小問題:MySQL會把第二個表達式理解爲一個別名。例如,在以下語句中,columnb被作爲別名對待:

mysql> SELECT columna columnb FROM mytable;

因此,使用AS明確地指定列的別名,把它作爲習慣,是一個良好的操作規範。

· 在一個WHERE子句中使用列別名是不允許的,因爲當執行WHERE子句時,列值可能還沒有被確定。請參見A.5.4節,“與列別名有關的問題”。

· FROM table_references子句指示行從哪些表中被恢復。如果您命名的表多於一個,則您在進行一個聯合操作。要了解有關聯合語法的說明,請參見13.2.7.1節,“JOIN語法”。對於每一個被指定的表,您可以自選地指定一個別名。

· tbl_name [[AS] alias]

· [{USE|IGNORE|FORCE} INDEX (key_list)]

使用USE INDEX、IGNORE INDEX、FORCE INDEX可以向優化符提示如何選擇索引。這部分內容在13.2.7.1節,“JOIN語法”中進行了討論。

您可以使用SET max_seeks_for_key=value作爲一種替代方法,來促使MySQL優先採用關鍵字掃描,替代表掃描。

· 您可以把當前數據庫中的一個表作爲tbl_name(在當前數據庫中)引用,或作爲db_name.tbl_name引用,來明確地指定一個數據庫。您可以把一列作爲col_name, tbl_name.col_name引用或作爲db_name.tbl_name.col_name引用。您不需要對一個列引用指定一個tbl_name或db_name.tbl_name前綴,除非此引用意義不明確。意義不明確時,要求指定明確的列引用格式。有關示例見9.2節,“數據庫、表、索引、列和別名”。

· 在沒有表被引用的情況下,允許您指定DUAL作爲一個假的表名。

· mysql> SELECT 1 + 1 FROM DUAL;

· -> 2

有些服務器要求一個FROM子句。DUAL僅用於與這些服務器兼容。如果沒有表被引用,則MySQL不要求該子句,前面的語句可以按以下方法編寫:

mysql> SELECT 1 + 1;

-> 2

· 使用tbl_name AS alias_name或tbl_name alias_name可以爲一個表引用起別名:

· mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2

· -> WHERE t1.name = t2.name;

· mysql> SELECT t1.name, t2.salary FROM employee t1, info t2

· -> WHERE t1.name = t2.name;

· 在WHERE子句中,您可以使用MySQL支持的所有函數,不過總計(總結)函數除外。請參見第12章:函數和操作符。

· 被選擇的用於輸出的列可以使用列名稱、列別名或列位置被引用到ORDER BY和GROUP BY子句中。列位置爲整數,從1開始:

· mysql> SELECT college, region, seed FROM tournament

· -> ORDER BY region, seed;

· mysql> SELECT college, region AS r, seed AS s FROM tournament

· -> ORDER BY r, s;

· mysql> SELECT college, region, seed FROM tournament

· -> ORDER BY 2, 3;

要以相反的順序進行分類,應把DESC(降序)關鍵字添加到ORDER BY子句中的列名稱中。默認值爲升序;該值可以使用ASC關鍵詞明確地指定。

不建議使用列位置,因爲該語法已經從SQL標準中刪除。

· 如果您使用GROUP BY,則輸出行根據GROUP BY列進行分類,如同您對相同的列進行了ORDER BY。MySQL對GROUP BY進行了擴展,因此您可以在各列(在子句中進行命名)的後面指定ASC和DESC:

· SELECT a, COUNT(b) FROM test_table GROUP BY a DESC

· MySQL對GROUP BY的使用進行了擴展,允許選擇在GROUP BY子句中沒有被提到的字段。如果您沒有得到預期的結果,請閱讀GROUP BY的說明,請參見12.10節,“與GROUP BY子句同時使用的函數和修改程序”。

· GROUP BY允許一個WITH ROLLUP修飾符。請參見12.10.2節,“GROUP BY修改程序”。

· HAVING子句基本上是最後使用,只位於被髮送給客戶端的條目之前,沒有進行優化。(LIMIT用於HAVING之後。)

SQL標準要求HAVING必須引用GROUP BY子句中的列或用於總計函數中的列。不過,MySQL支持對此工作性質的擴展,並允許HAVING因爲SELECT清單中的列和外部子查詢中的列。

如果HAVING子句引用了一個意義不明確的列,則會出現警告。在下面的語句中,col2意義不明確,因爲它既作爲別名使用,又作爲列名使用:

mysql> SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;

標準SQL工作性質具有優先權,因此如果一個HAVING列名既被用於GROUP BY,又被用作輸出列清單中的起了別名的列,則優先權被給予GROUP BY列中的列。

· HAVING不能用於應被用於WHERE子句的條目。例如,不能編寫如下語句:

· mysql> SELECT col_name FROM tbl_name HAVING col_name > 0;

而應這麼編寫:

mysql> SELECT col_name FROM tbl_name WHERE col_name > 0;

· HAVING子句可以引用總計函數,而WHERE子句不能引用:

· mysql> SELECT user, MAX(salary) FROM users

· -> GROUP BY user HAVING MAX(salary)>10;

(在有些較早版本的MySQL中,本語句不運行。)

· LIMIT子句可以被用於限制被SELECT語句返回的行數。LIMIT取一個或兩個數字自變量,自變量必須是非負的整數常數(當使用已預備的語句時除外)。

使用兩個自變量時,第一個自變量指定返回的第一行的偏移量,第二個自變量指定返回的行數的最大值。初始行的偏移量爲0(不是1):

mysql> SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15

爲了與PostgreSQL兼容,MySQL也支持LIMIT row_count OFFSET offset語法。

如果要恢復從某個偏移量到結果集合的末端之間的所有的行,您可以對第二個參數是使用比較大的數。本語句可以恢復從第96行到最後的所有行:

mysql> SELECT * FROM tbl LIMIT 95,18446744073709551615;

使用1個自變量時,該值指定從結果集合的開頭返回的行數:

mysql> SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows

換句話說,LIMIT n與LIMIT 0,n等價。

對於已預備的語句,您可以使用位置保持符。以下語句將從tb1表中返回一行:

mysql> SET @a=1;

mysql> PREPARE STMT FROM "SELECT * FROM tbl LIMIT ?";

mysql> EXECUTE STMT USING @a;

以下語句將從tb1表中返回第二到第六行:

mysql> SET @skip=1; SET @numrows=5;

mysql> PREPARE STMT FROM "SELECT * FROM tbl LIMIT ?, ?";

mysql> EXECUTE STMT USING @skip, @numrows;

· SELECT...INTO OUTFILE 'file_name'形式的SELECT可以把被選擇的行寫入一個文件中。該文件被創建到服務器主機上,因此您必須擁有FILE權限,才能使用此語法。file_name不能是一個原有的文件。原有文件會阻止例如“/etc/passwd”的文件和數據庫表被銷燬。

SELECT...INTO OUTFILE語句的主要作用是讓您可以非常快速地把一個錶轉儲到服務器機器上。如果您想要在服務器主機之外的部分客戶主機上創建結果文件,您不能使用SELECT...INTO OUTFILE。在這種情況下,您應該在客戶主機上使用比如“mysql –e "SELECT ..." > file_name”的命令,來生成文件。

SELECT...INTO OUTFILE是LOAD DATA INFILE的補語;用於語句的exort_options部分的語法包括部分FIELDS和LINES子句,這些子句與LOAD DATA INFILE語句同時使用。請參見13.2.5節,“LOAD DATA INFILE語法”。

FIELDS ESCAPED BY用於控制如何寫入特殊字符。如果FIELDS ESCAPED BY字符不是空字符,則被用於在輸出中對以下字符設前綴:

o FIELDS ESCAPED BY字符

o FIELDS [OPTIONALLY] ENCLOSED BY字符

o FIELDS TERMINATED BY和LINES TERMINATED BY值的第一個字符

o ASCII 0(在編寫時接在轉義符後面的是ASCII ‘0’,而不是一個零值字節)

如果FIELDS ESCAPED BY字符是空字符,則沒有字符被轉義,並且NULL被作爲NULL輸出,而不是作爲\N輸出。指定一個空的轉義符不是一個好的主意。特別是當您的數據中的字段值包含剛被給予的清單中的字符時,更是如此。

其原因是您必須對所有FIELDS TERMINATED BY, ENCLOSED BY, ESCAPED BY或LINES TERMINATED BY字符進行轉義,才能可靠地讀取文件並返回。ASCII NUL被轉義,以便更容易地使用調頁程序觀看。

生成的文件不必符合SQL語法,所以沒有其它的字符需要被轉義。

在下面的例子中,生成一個文件,各值用逗號隔開。這種格式可以被許多程序使用。

SELECT a,b,a+b INTO OUTFILE '/tmp/result.text'

FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'

LINES TERMINATED BY '\n'

FROM test_table;

· 如果您使用INTO DUMPFILE代替INTO OUTFILE,則MySQL只把一行寫入到文件中,不對任何列或行進行終止,也不執行任何轉義處理。如果您想要把一個BLOB值存儲到文件中,則這個語句是有用的。

· 註釋:任何由INTO OUTFILE或INTO DUMPFILE創建的文件都可以被服務器主機上的所有用戶編寫。原因是,MySQL服務器不能創建這樣的文件,即文件的所有者不是該文件運行時所屬的用戶(任何時候,您都不能出於此原因或出於其它原因把mysqld作爲根段運行)。該文件必須是全局可寫的,這樣您就可以操作其中的內容。

· 有的過程應在結果集合內處理數據。PROCEDURE子句用於對這些過程進行命名。要了解示例,請參見27.3.1節,“步驟分析”。

· 存儲引擎使用頁面或行鎖。如果您對存儲引擎使用FOR UPDATE,則受到查詢檢驗的行會被進行寫鎖定,直到當前事務結束爲止。使用LOCK IN SHARE MODE可以設置一個共享鎖。共享鎖可以防止其它事務更新或刪除被檢驗的行。請參見15.2.10.5節,“鎖定讀取SELECT ... FOR UPDATE和SELECT ... LOCK IN SHARE MODE”。

在SELECT關鍵詞的後面,您可以使用許多選項。這些選項可以影響語句的運行。

ALL, DISTINCT和DISTINCTROW選項指定是否重複行應被返回。如果這些選項沒有被給定,則默認值爲ALL(所有的匹配行被返回)。DISTINCT和DISTINCTROW是同義詞,用於指定結果集合中的重複行應被刪除。

HIGH_PRIORITY, STRAIGHT_JOIN和以SQL_爲開頭的選項是MySQL相對於標準SQL的擴展。

· HIGH_PRIORITY給予SELECT更高的優先權,高於用於更新表的語句。您應該只對查詢使用HIGH_PRIORITY。查詢速度非常快,而且立刻被執行。SELECT HIGH_PRIORITY查詢在表被鎖定用於讀取時被髮出。即使有一個新的語句正在等待表變爲空閒,查詢也會運行。

HIGH_PRIORITY不能和SELECT語句同時使用。SELECT語句是UNION的一部分。

· STRAIGHT_JOIN用於促使優化符把表聯合在一起,順序按照這些表在FROM子句中排列的順序。如果優化符聯合表時順序不佳,您可以使用STRAIGHT_JOIN來加快查詢的速度。請參見7.2.1節,“EXPLAIN語法(獲取關於SELECT的信息)”。STRAIGHT_JOIN也可以被用於table_references清單中。請參見13.2.7.1節,“JOIN語法”。

· SQL_BIG_RESULT可以與GROUP BY或DISTINCT同時使用,來告知優化符結果集合有很多行。在這種情況下,MySQL直接使用以磁盤爲基礎的臨時表(如果需要的話)。在這種情況下,MySQL還會優先進行分類,不優先使用臨時表。臨時表對於GROUP BY組分帶有關鍵字。

· SQL_BUFFER_RESULT促使結果被放入一個臨時表中。這可以幫助MySQL提前解開表鎖定,在需要花費較長時間的情況下,也可以幫助把結果集合發送到客戶端中。

· SQL_SMALL_RESULT可以與GROUP BY或DISTINCT同時使用,來告知優化符結果集合是較小的。在此情況下,MySAL使用快速臨時表來儲存生成的表,而不是使用分類。在MySQL 5.1中,通常不需要這樣。

· SQL_CALC_FOUND_ROWS告知MySQL計算有多少行應位於結果集合中,不考慮任何LIMIT子句。行的數目可以使用SELECT FOUND_ROWS()恢復。請參見12.9.3節,“信息函數”。

· 如果您正在使用一個query_cache_type值,值爲2或DEMAND,則SQL_CACHE告知MySQL把查詢結果存儲在查詢緩存中。對於使用UNION的查詢或子查詢,本選項會影響查詢中的所有SELECT。請參見5.13節,“MySQL查詢高速緩衝”。

· SQL_NO_CACHE告知MySQL不要把查詢結果存儲在查詢緩存中。請參見5.13節,“MySQL查詢高速緩衝”。對於一個使用UNION或子查詢的查詢,本選項會影響查詢中的SELECT。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章