MySQL必知必會 第7-9章

第七章 數據過濾

7.1 組合WHERE子句

在第六章介紹的所有WHERE子句在過濾時,使用的都是單一的條件。為了進行更強的過濾控制,MySQL允許給出多個WHERE子句,并通過ANDOR操作符的方式組合使用。

  • 操作符(operator)
    用來聯接或改變WHERE子句中關鍵字,也成為邏輯操作符。
7.1.1 AND操作符

AND操作符可以使用對多列的條件進行累加過濾。

  • 輸入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id = 1003 AND prod_price <= 10;
  • 輸出:略
  • 分析:此語句檢索由供應商1003制造,且價格小于等于10美元的產品的編號、名稱和價格。AND操作符“并且”的語意。
7.1.2 OR操作符

OR操作符可以使用對多列的條件進行累加過濾。

  • 輸入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id = 1002 OR vend_id = 1003;
  • 輸出:略
  • 分析:此語句檢索由供應商1002或1003制造的所有產品的編號、名稱和價格。OR操作符“或者”的語意。
7.1.3 計算次序

WHERE子句可包含任意數目的ANDOR操作符。但是AND的優先級比OR高,應使用適當的圓括號分組操作符。

  • 輸入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE (vend_id = 1002 OR vend_id = 1003) AND prod_price >= 10;
  • 輸出:略
  • 分析:此語句檢索由供應商為1002,或1003,價格大于等于10美元的所有產品的編號、名稱和價格。如果沒有加圓括號,則 vend_id = 1003 先和 prod_price >= 10 進行AND操作,再與vend_id = 1002進行OR操作,得不到想要的結果。

注意:任何時候都不應該過分依賴默認計算次序,使用圓括號可以增加可讀性,消除歧義。

7.2 IN操作符

IN操作符用來指定條件范圍,范圍中每個條件都可以進行匹配。IN的合法值由逗號分隔,并全部括在圓括號中。

  • 輸入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id IN (1002,1003);
  • 輸出:略
  • 分析:此語句檢索由供應商1002或1003制造的所有產品的編號、名稱和價格。所完成的功能與OR類似。

使用IN的優點為:

  • 在使用長的合法選項清單時,IN操作符的語法更清楚更直觀。
  • IN操作符比OR操作符清單執行更快
  • IN操作符最大的優點是可以包含其他SELECT語句(將在14章說明),能夠更動態地建立WHERE子句。
7.3 NOT操作符

WHERE子句中的NOT操作符有且只有一個功能,就是否定它之后的任何條件。

  • 輸入:
    SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id NOT IN (1002,1003);
  • 輸出:略
  • 分析:此語句檢索由供應商1002或1003以外供應商提供的所有產品的編號、名稱和價格。

注意:MySQL支持使用NOT對IN、BETWEEN和EXISTS子句取反,這與其他大多數DBMS允許使用NOT對各種條件取反有很大區別。

第八章 使用通配符進行過濾

8.1 LIKE操作符

之前介紹的都是針對已知值的過濾。而對進行未知內容的匹配,可以使用通配符創建比較數據的搜索模式來完成。通配符的匹配,需要通過LIKE操作符指示MySQL完成。

  • 通配符
    用來匹配值的一部分的特殊字符。

  • 搜索模式
    由字面值、通配符或兩者組合成的搜索條件。

  • 謂詞
    從技術上說,LIKE是謂詞而不是操作符,雖然結果是相同的,但是需要明白此術語。

8.1.1 百分號(%)通配符

%表示任何字符出現任意次。例如,為了找到所有以 jet起頭的產品,可使用以下SELECT語句

  • 輸入:
    SELECT prod_id, prod_name FROM products WHERE prod_name LIKE 'jet%';
  • 輸出:略
  • 分析:此例子使用了搜索模式 'jet%',它告訴MySQL接受jet之后任意字符,不管有多少字符。

注意:

  • %通配符可放在搜索模式的任意位置,例如 '%anvil%' 表示匹配任何位置包含anvil的字符; 's%e'表示以s開頭以e結尾的字符。
  • %除了可以匹配一個或者多個字符外,還可以匹配0個字符。%代表給定位置的0、1或多個字符。
  • 尾空格將影響匹配結果:'%anvil '將匹配不到anvil_Blank
  • WHERE prod_name LIKE '%'也無法匹配NULL值作為產品名的行。
8.1.2 下劃線(_)通配符

下劃線(_)通配符只匹配單個字符而不是多個字符。

  • 輸入:
    SELECT prod_id, prod_name FROM products WHERE prod_name LIKE '_ ton anvil';
  • 輸出:略
  • 分析:此例子使用了搜索模式 '_ ton anvil',它能夠匹配1 ton anvil2 ton anvil ,但不能匹配 .5 ton anvil,因為下劃線通配符只對應一個字,不可多也不能少 。

通配符使用技巧:

  • 通配符的處理通常比值匹配花費的時間更多。不要過度使用通配符,能夠用其他操作符達到同樣目的時,應使用其他操作符。
  • 除非確實有必要,否則盡量不要在模式搜索開始時使用通配符,否則速度尤其慢。
  • 仔細注意通配符的位置,錯誤的位置將得不到想要的結果。

第九章 使用正則表達式進行搜索

9.1 正則表達式介紹

正則表達式是用來匹配文本的特殊串(字符集合),所有種類的程序設計語言、文本編輯器、操作系統等都支持正則表達式。

9.2 使用MySQL正則表達式

MySQL中的正則表達式僅是正則表達式的一個子集。

9.2.1 基本字符匹配
  • 輸入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '1000';

  • 輸出:略

  • 分析:除關鍵詞字LIKEREGEXP替代外,這條語句看上去非常像LIKE語句,但不同在于LIKE匹配整個行,REGEXP在列值中進行匹配,如果被匹配的值在文本中出現則匹配成功。因此,對于以上輸入,REGEXP可以匹配到 Jet 1000,但LIKE則匹配不到。REGEXP可以通過定位符的使用,來匹配整個行,將在9.2.8中介紹定位符。

  • 輸入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '.000';

  • 輸出:略

  • 分析:這里使用了正則表達式'.000'.是正則表達式語言中一個特殊的字符。它表示匹配任意一個字符。因此JetPack 1000·JetPack 2000都可以匹配返回。

9.2.2 進行OR匹配

為搜索兩個串之一,使用(|)。

  • 輸入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '1000|2000' ORDER BY prod_name ;
  • 輸出:略
  • 分析:這里使用了正則表達式'1000|2000'|是正則表達式語言中的OR操作符。另外,|還支持兩個以上的條件,例如'1000|2000|3000'
9.2.3 匹配幾個字符之一

如果想匹配特定的單一字符,可以使用[]將一組指定的內容括起來。

  • 輸入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '[123] ton' ORDER BY prod_name ;
    *輸出:略
    分析:這里使用了正則表達式'[123] ton'[123]定義一組字符,意為匹配1、2或3。因此,1 ton2 ton3 ton都能匹配。[]是另一種形式的OR語句。

注意:

  • 事實上,'[123] ton''[1|2|3] ton'的縮寫,也可以使用后者。
  • WHERE prod_name REGEXP '1|2|3 ton'并不能得到想要的答案,因為被MySQL理解為'1''2'‘3 ton’
  • 字符集也可用于否定,只需要在集合開始處放置一個^即可。例如[^123]可以匹配'1''2''3'以外的其他字符。
9.2.4 匹配范圍

集合可用來定義要匹配一個或多個字符,此時可以使用-來定義一個范圍,例如[0-9]表示數字0到9,[a-z]表示字母a到z。

  • 輸入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '[1-5] ton' ORDER BY prod_name ;
  • 輸出:略
  • 分析:這里使用了正則表達式'[1-5] ton'[1-5]定義了一個范圍,表示數字1到5。
9.2.5 匹配特殊字符

正則表達式語句由具有特定含義的特殊字符構成。例如|-等。如果要表示一些特殊的字母,如含.的值,則應該使用\\\為前導。\\\-表示查找-\\\.表示查找.

  • 輸入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '\\\.' ORDER BY prod_name ;
  • 輸出:略
  • 分析:這里使用了正則表達式'\\\.',可以順利匹配到.。這種處理方式就是所謂的轉義,正則表達式內具有特殊意義的所有字符都需要轉義。包括. | [ ]等,\\\\也用來引用元字符,如下:

注意:

  • 為匹配\\應使用\\\\\
  • 多數正則表達式實現單個反斜桿轉義特殊字符。但MySQL要求兩個反斜桿(MySQL自己解釋一個,正則表達式解釋一個)。
9.2.6 匹配字符類

為方便常見字符集的查找,可以使用預定義的字符集。稱為字符類。如下圖所示:

9.2.7 匹配多個實例

目前為止使用的所有正則表達式都試圖匹配單詞出現。但有時需要對匹配的數目進行更強的控制,此時可以使用下列正則表達式重復元字符來完成。

  • 輸入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '\\\([0-9] sticks?\\\)' ORDER BY prod_name ;

  • 輸出:略
    分析:這里使用了正則表達式'\\\([0-9] sticks?\\\)'?表示,它前面的字母s出現0次或1次。

  • 輸入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '[[:digit:]]{4}' ORDER BY prod_name ;

  • 輸出:略

  • 分析:這里使用了正則表達式'[[:digit:]]{4}',表示匹配連在一起的四位數字。

注意:使用正則表達式時,編寫某個特定的表達式幾乎總是有多種方法。

9.2.8 定位符

目前為止,所有例子都是匹配一個串中任意位置的文本,為了匹配特定位置的文本,需要使用定位符。

  • 輸入:
    SELECT prod_name FROM products WHERE prod_name REGEXP '^[0-9\\.]' ORDER BY prod_name ;
  • 輸出:略
  • 分析:^匹配串的開始,'^[0-9\\\.]' 表示匹配以數字或.開始的串。

注意:

  • ^有兩個用法,在集合中(用[]定義),用來表示幾何的否定,在集合外,用來表示串的起始。
  • REGEXP用來匹配子串,LIKE用來匹配整個串,REGEXP^做開頭,用$為結束時,作用與LIKE相同。
  • 可在不使用數據庫的情況下,對正則表達式做簡單測試,REGEXP檢查總是返回0或1,后者表示匹配成功。例如:SELECT 'hello' FROM ‘[0-9]';將返回0。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容