本文針對MySQL資料庫中的SELECT語句快速且精細掌握。
MySQL中SELECT語句的基本語法是:
以下是引用片段:
SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT]
[SQL_BIG_RESULT] [HIGH_PRIORITY]
[DISTINCT|DISTINCTROW|ALL]
select_list
[INTO {OUTFILE|DUMPFILE} 'file_name' export_options]
[FROM table_references [WHERE where_definition]
[GROUP BY col_name,...] [HAVING where_definition]
[ORDER BY {unsighed_integer|col_name|formura} [ASC|DESC],...]
[LIMIT [offset,] rows] [PROCEDURE procedure_name]]
從這個基本語法可以看出,最簡單的SELECT語句是SELECT select_list,實際上利用這個最簡單的SELECT語句,你也可以完成許多你期待的功能,首先你能利用它進行MySQL所支援的任何運算,例如:SELECT 1+1,它將返回2;其次,你也能利用它來給變數賦值,而在PHP中,運用SELECT語句的這種功能,你就可以自由地運用MySQL的函數為PHP程式進行各種運算,並賦值給變數。在很多的時候,你會發現MySQL擁有許多比PHP更強大的函數。
STRAIGHT_JOIN、SQL_SMALL_RESULT、SQL_BIG_RESULT、HIGH_PRIORITY是MySQL對ANSI SQL92的擴充。如果優化器以非最佳次序連結表,使用STRAIGHT_JOIN可以加快查詢。
SQL_SMALL_RESULT和SQL_BIG_RESULT是一組相對的關鍵字。它們必須與GROUP BY、DISTINCT或DISTINCTROW一起使用。 SQL_SMALL_RESULT告知優化器結果會很小,要求MySQL使用臨時表儲存最終的表而不是使用排序;反之,SQL_BIG_RESULT告知優化器結果會很小,要求MySQL使用排序而不是做臨時表。
HIGH_PRIORITY將賦予SELECT比一個更新表的語句更高的優先權,使其可以進行一次優先的快速的查詢。
以上四個關鍵字的使用方法的確比較晦澀。幸運的是,在絕大多數情況下,在MySQL中我們完全可以選擇不使用這四個關鍵字。
DISTINCT、DISTINCTROW對查詢傳回的結果集提供了一個最基本但很有用的篩選。那就是結果集中只含非重複行。這裡要注意的是,對於關鍵字DISTINCT、DISTINCTROW來說,空值都是相等的,無論有多少NULL值,只選一個。而ALL的用法就有畫蛇添足之嫌了。它對結果集的產生沒有任何影響。
INTO {OUTFILE|DUMPFILE} 'file_name' export_options,將結果集寫入一個檔案。檔案在伺服器主機上被創建,並且不能是已經存在的。語句中的export_options部分的語法與用在LOAD DATAINFILE語句中的FIELDS和LINES子句中的相同,我們將在MySQL進階_LOAD DATA篇中詳細討論它。而OUTFILE與DUMPFILE的關鍵字的差別是:後前只寫一行到文件,並沒有任何列或行結束。
select list:其中可以包含一項或多項下列內容:
1、“*”,表示按照create table的順序排列的所有欄位。
2、依照使用者所需順序排列的列名的清單。
3.可以使用別名取代列名,形式如下:column name as column_heading。
4、表達式(列名、常數、函數,或以算術或逐位運算子連接的列名、常數和函數的任何組合)。
5、內部函數或集合函數。
6、上述各項的任何一種組合。
FROM:決定SELECT指令中使用哪些表。一般都要求有此項,除非select_list中不含列名(例如,只有常數、算術表達式等)。如果表項中有多個表,請用逗號將之分開。在關鍵字FROM後面的表的順序不影響結果。
表名可以給予相關別名,以便使表達清晰。這裡的語法是tbl_name [AS] 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是完全等價的。
所有對該表的其他引用,例如在where子句和having子句中,都要用別名,別名不能以數字開頭。
where子句設定了搜尋條件,它在insert,update,delete語句中的應用方法也與在select語句中的應用方法完全相同。搜尋條件緊接在關鍵字where的後面。如果使用者要在語句中使用多個搜尋條件,則可用and或or連接。搜尋條件的基本語法是[not] expression comparison_operator expression;[not] expression [not] like “match_string”;[not] expression is [not] null;[not] expression [not] between expression and expression;[not] column_name join_operator column_name;[not] boolean_expression。
and:用來聯結兩個條件,並在兩個條件都是TRUE的時候回傳結果。當在同一語句中使用多個邏輯運算子時,and運算子總是最優先,除非使用者用括號改變了運算順序。
或:用來聯結兩個條件,當兩個條件中有任一條件是TRUE的時候回傳結果。當在同一語句中使用多個邏輯運算子時,運算子or通常在運算子and之後進行運算。當然使用者可以使用括號改變運算的順序。
between:用來識別範圍下限的關鍵字,and後面跟著範圍上限的值。範圍where @val between x and y包含首尾值。如果between後面指定的第一個值大於第二個值,則該查詢不傳回任何行。
column_name:在比較中使用的列名。在會產生歧義時,一定要指明列所在的表名。
comparison_operator:比較運算子。見下表:
以下是引用片段:
符號 意義
= 等於
> 大於
< 小於
>= 大於等於
<= 小於等於
!= 不等於
<> 不等於
在比較char,varchar型資料時,「<」的意思是更接近字母表頭部,「>」代表更接近字母表尾部。一般來說,小寫字母大於大寫字母,大寫字母大於數字,但這可能依賴伺服器上作業系統的比較順序。
在比較時,末尾的空格是被忽略的。例如,“Dirk”等於“Dirk ”。
在比較日期時,「<」表示早於,「>」表示晚於。
在使用比較運算子比較character和datetime資料時,需用引號將所有資料引起來。
expression:可能是列名、常數、函數或列名或常數的任意組合,以及以算術運算子或逐位運算子連接的函數。算術運算子如下表所示:
以下是引用片段:
符號 意義
+ 加號
- 減號
* 乘號
/ 除號
is null:在搜尋一個NULL值時使用。
like:關鍵字,對char、varchar和datetime(不包括秒和毫秒)可以使用like,在MySQL中like也可以用在數字的表達式上。
當使用者在搜尋datetime型資料時,最好是使用關鍵字like,因為完整的datetime記錄包含各種各樣的日期元件。例如使用者在列arrival_time中加入一個值“9:20”,而子句where arrival_time=“9:20”卻沒有發現它,因為MySQL把錄入的資料轉換成了“Jan 1,1900 9:20AM”。然而子句where arrival_time like「%9:20%」就能找到它。
boolean_expression:傳回「true」或「false」值的表達式。
match_string:由字元和通配符組成的字串,用單引號或雙引號引起來,是匹配模式。通配符如下表所示:
以下是引用片段:
符號 意義
% 0或多個字元的字串
_ 任何單一字符
not: 否定任何邏輯表達式,或是關鍵字,
如like,null,between等。
group by和having子句在select語句中使用,
可以將表格分割成群組並傳回符合having子句條件的群組。
語法:select語句開頭
group by [all] aggregate_free_expression [,aggregate_free_expression]*
[having search_conditions]
select語句結尾
group by:指定表格將分割的群組群,如果在select表項中包含集合函數,則為各組計算一個總計值。這些總計值的結果以新的欄位顯示,而不是新的行。在having子句中使用者可以引用這些新的總計欄位。在group by之前的select_list中可以使用avg、count、max、min和sum等集合函數。表可以被任意列的組合分組。
all:在結果中包含所有組群的Transact-SQL擴展,這裡的所有組群甚至包括那些被where子句所排除的組群。如果同時使用having子句,將對all的意義否定。
aggregate_free_expression:不包含集合函數的表達式,Transact-SQL擴充允許在以列名稱分組的同時,以無集合函數的表達式分組。
having:為group by子句設定條件,類似where為select語句設定條件的方法。 having的查找條件可以包含集合函數表達式。除此之外,它的查找條件與where查找條件相同。
order by:按列排列結果。 select輸出的列可以用列名、列別名或列位置來引用。例如:select id as myid,name as myname from mytable group by id、select id as myid,name as myname from mytable group by myid、select id as myid,name as myname from mytable group by 1三句是完全等價這三句是完全等價這三句是完全等價這三句是完全等價這三句話是完全等價這三句的。當然,我們不贊成用第三種用法,這將對程式的可讀性帶來不好的影響。 為了以降序排列,把DESC關鍵字加到order by子句中你要排序的列名前。預設是升序,你也可以用ASC關鍵字明確指定。
limit 子句:用來限制select語句傳回的行數。 limit取1或2個數字參數,如果給定2個參數,第一個指定要回傳的第一行的偏移量,第二個指定回傳行的最大數目。初始行的偏移量是0(不是1)。如果給定一個參數,它指出偏移量為0的返回行的最大數目。也就是說limit 5和limit 0,5完全等價。
至於procedure關鍵字的含義,我也沒搞得太清楚,好像是對儲存過程的支持,而MySQL本身不支援儲存過程,看來是為了將來擴充的需要而保留的吧。