本文針對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運算子總是最優先,除非使用者用括弧改變了運算順序。
or:用來連接兩個條件,當兩個條件中有任一條件是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等集合
在你的工作中是否會為了某個活動要隨機取出一些合格EMAIL或者手機號碼使用者,來頒發獲獎通知或其它訊息?本文以執行個體的方式來講解如何抽取隨機數的多種方法。
如果是的話,可以用oracle裡產生隨機數的PL/SQL, 目錄檔案名稱在:/ORACLE_HOME/rdbms/admin/dbmsrand.sql。
用之前先要在sys使用者下編譯:SQL>@/ORACLE_HOME/rdbms/admin/dbmsrand.sql。
它實際是在sys使用者下產生一個dbms_random程式包,同時產生公有同義字,並授權給所有資料庫使用者有執行的許可權。
使用dbms_random程式包, 取出隨機資料的方法:
1. 先建立一個唯一增長的序號tmp_id:
以下是引用片段:
create sequence tmp_id increment by 1 start with 1 maxvalue 9999999 nocycle nocache;
2. 然後建立一個暫存資料表tmp_1,把符合本次活動條件的記錄全部取出來:
以下是引用片段:
create table tmp_1 as select tmp_id.nextval as id, email,mobileno from 表名 where 條件;
找到最大的id號:select max(id) from tmp_1;。
3. 設定一個產生隨機數的種子:
以下是引用片段:
execute dbms_random.seed(12345678); 或者 execute dbms_random.seed (TO_CHAR(SYSDATE,'MM-DD-YYYY HH24:MI:SS'));
4. 調用隨機數產生函數dbms_random.value產生暫存資料表tmp_2(假設隨機取200個):
以下是引用片段:
create table tmp_2 as select trunc (dbms_random.value(1,5000)) as id from tmp_1 where rownum<201;
[ 說明:dbms_random.value(1,5000)是取1到5000間的隨機數,會有小數,
trunc函數對隨機數字取整,才能和暫存資料表的整數ID欄位相對應。
注意:如果tmp_1記錄比較多(10萬條以上),也可以找一個約大於兩百行的表(假如是tmp_3)來產生tmp_2
以下是引用片段:
create table tmp_2 as select trunc(dbms_random.value(1,5000)) as id from tmp_3 where rownum<201; ]
5. tmp_1和tmp_2相關聯取得合格200使用者
以下是引用片段:
select t1.mobileno,t1.email from tmp_1 t1,
tmp_2 t2 where t1.id=t2.id;
[ 注意:如果tmp_1記錄比較多(10萬條以上),需要在id欄位上建索引。]
也可以輸出到文字檔:
以下是引用片段:
set pagesize 300;
spool /tmp/200.txt;
select t1.mobileno,t1.email from tmp_1 t1,
tmp_2 t2 where t1.id=t2.id order by t1.mobileno;
spool off;
6. 用完後,刪除暫存資料表tmp_1、tmp_2和序號tmp_id。
本文整理於互連網,歡迎原文作者來信署名著作權 zujizhe@chinaz.com