數(shù)據(jù)過濾
1. 組合WHERE子句
? 為了進(jìn)行更強(qiáng)的過濾控制傍衡,MySQL允許給出多個(gè)WHERE子句贪磺。這些子句可以兩種方式使用:以AND子句的方式或OR子句的方式使用拟蜻。
操作符(operator) 用來聯(lián)結(jié)或改變WHERE子句中的子句的關(guān)鍵字拯田。也稱為邏輯操作符(logical operator)勒奇。
1.1 AND操作符
? 為了通過不止一個(gè)列進(jìn)行過濾,可使用AND操作符給WHERE子句附加條件濒募。下面的代碼給出了一個(gè)例子:
輸入:
SELECT prod_id,prod_price,prod_name
FROM products
WHERE vend_id = 1003 AND prod_price <= 10;
分析:此SQL語句檢索由供應(yīng)商1003制造且價(jià)格小于等于10美元的所有產(chǎn)品的名稱和價(jià)格鞭盟。這條SELECT語句中的WHERE子句包含兩個(gè)條件,并且用AND關(guān)鍵字聯(lián)結(jié)它們瑰剃。AND指示DBMS只返回滿足所有給定條件的行齿诉。如果某個(gè)產(chǎn)品由供應(yīng)商1003制造,但它的價(jià)格高于10美元,則不檢索它粤剧。類似歇竟,如果產(chǎn)品價(jià)格小于10美元,但不是由指定供應(yīng)商制造的也不被檢索抵恋。這條SQL語句產(chǎn)生的輸出如下:
輸出:
prod_id | prod_price | prod_name |
---|---|---|
FB | 10.00 | Bird seed |
FC | 2.50 | Carrots |
SLING | 4.49 | Sling |
TNT1 | 2.5 | TNT(1 stick) |
TNT2 | 10.00 | TNT(5 sticks) |
AND 用在WHERE子句中的關(guān)鍵字焕议,用來指示檢索滿足所有給定條件的行。
1.2 OR操作符
? OR操作符與AND操作符不同弧关,它指示MySQL檢索匹配任一條件的行盅安。
? 請(qǐng)看如下的SELECT語句:
輸入:
SELECT prod_name,prod_price
FROM products
WHERE vend_id = 1002 OR vend_id = 1003;
分析:此SQL語句檢索由任一個(gè)指定供應(yīng)商制造的所有產(chǎn)品的產(chǎn)品名和價(jià)格。OR操作符告訴DBMS匹配任一條件而不是同時(shí)匹配兩個(gè)條件世囊。如果這里使用的是AND操作符宽堆,則沒有數(shù)據(jù)返回。這條SQL語句產(chǎn)生的輸出如下:
輸出:
prod_name | prod_price |
---|---|
Detonator | 13.00 |
Bird seed | 10.00 |
Carrots | 2.50 |
Fuses | 3.42 |
Oil can | 8.99 |
Safe | 50.00 |
Sling | 4.49 |
TNT(1 stick) | 2.50 |
TNT(5 sticks) | 10.00 |
OR WHERE子句中使用的關(guān)鍵字茸习,用來表示檢索匹配任一給定條件的行畜隶。
1.3 計(jì)算次序
? WHERE可包含任意數(shù)目的AND和OR操作符。允許兩者結(jié)合以進(jìn)行復(fù)雜和高級(jí)的過濾号胚。
? 但是組合AND和OR帶來了一個(gè)有趣的問題籽慢。為了說明這個(gè)問題,來看一個(gè)例子猫胁。假如需要列出價(jià)格為10美元(含)以上且由1002或1003制造的所有產(chǎn)品箱亿。下面的SELECT語句使用AND和OR操作符的組合建立了一個(gè)WHERE子句:
輸入:
SELECT prod_name,prod_price
FROM products
WHERE vend_id = 1002 OR vend_id = 1003 AND prod_price >=10;
輸出:
prod_name | prod_price |
---|---|
Detonator | 13.00 |
Bird seed | 10.00 |
Fuses | 3.42 |
Oil can | 8.99 |
Safe | 50.00 |
TNT(5 sticks) | 10.00 |
分析:請(qǐng)看上面的結(jié)果。返回的行中有兩行價(jià)格小于10美元弃秆,顯然届惋,返回的行未按預(yù)期的進(jìn)行過濾。為什么會(huì)這樣呢菠赚?原因在于計(jì)算的次序脑豹。SQL(像多數(shù)語言一樣)在處理OR操作符前,優(yōu)先處理AND操作符衡查。當(dāng)SQL看到上述WHERE子句時(shí)瘩欺,它理解為由供應(yīng)商1003制造的任何價(jià)格為10美元(含)以上的產(chǎn)品,或者由供應(yīng)商1002制造的任何產(chǎn)品拌牲,而不管其價(jià)格如何俱饿。換句話說,由于AND在計(jì)算次序中優(yōu)先級(jí)更高塌忽,操作符被錯(cuò)誤地組合了拍埠。
? 此問題的解決方法是使用圓括號(hào)明確地分組相應(yīng)的操作符。請(qǐng)看下面的SELECT語句及輸出:
輸入:
SELECT prod_name,prod_price
FROM products
WHERE (vend_id = 1002 OR vend_id = 1003) AND prod_price >=10;
輸出:
prod_name | prod_price |
---|---|
Detonator | 13.00 |
Bird seed | 10.00 |
Safe | 50.00 |
TNT(5 sticks) | 10.00 |
分析:這條SELECT語句與前一條的唯一差別是土居,這條語句中枣购,前兩個(gè)條件用圓括號(hào)括了起來嬉探。因?yàn)閳A括號(hào)具有較AND或OR操作符高的計(jì)算次序,DBMS首先過濾圓括號(hào)內(nèi)的OR條件坷虑。這時(shí),SQL語句變成了選擇由供應(yīng)商1002或1003制造的且價(jià)格都在10美元(含)以上的任何產(chǎn)品埂奈,這正是我們所希望的迄损。
在WHERE子句中使用圓括號(hào) 任何時(shí)候使用具有AND和OR操作符的WHERE子句句,都應(yīng)該使用圓括號(hào)明確地分組操作符账磺。不要過分依賴默認(rèn)計(jì)算次序芹敌,即使它確實(shí)是你想要的東西也是如此。使用圓括號(hào)沒有什么壞處垮抗,它能消除歧義氏捞。
2.IN操作符
? 圓括號(hào)在WHERE子句中海油另外一種用法。IN操作符用來指定條件范圍冒版,范圍中的每個(gè)條件都可以進(jìn)行匹配液茎。IN取合法值的逗號(hào)分隔的清單,全都括在圓括號(hào)中辞嗡。下面的例子說明了這個(gè)操作符:
輸入:
SELECT prod_name,prod_price
FROM products
WHERE vend_id IN (1002,1003)
ORDER BY prod_name;
輸出:
prod_name | prod_price |
---|---|
Bird seed | 10.00 |
Carrots | 2.50 |
Detonator | 13.00 |
Fuses | 3.42 |
Oil can | 8.99 |
Safe | 50.00 |
Sling | 4.49 |
TNT(1 stick) | 2.5 |
TNT(5 sticks) | 10.00 |
分析:此SELECT語句檢索供應(yīng)商1002和1003制造的所有產(chǎn)品捆等。IN操作符后跟由逗號(hào)分隔的合法值清單,整個(gè)清單必須括在圓括號(hào)中续室。
? 如果你認(rèn)為IN操作符完成與OR相同的功能栋烤,那么你的這種猜測(cè)是對(duì)的。下面的SQL語句完成與上面的例子相同的工作:
輸入:
SELECT prod_name,prod_price
FROM products
WHERE vend_id = 1002 OR vend_id = 1003
ORDER BY prod_name;
為什么要使用IN操作符挺狰?其優(yōu)點(diǎn)具體如下明郭。
- 在使用長的合法選項(xiàng)清單時(shí),IN操作符的語法更清楚且更直觀丰泊。
- 在使用IN時(shí)薯定,計(jì)算的次序更容易管理(因?yàn)槭褂玫牟僮鞣伲?/li>
- IN操作符一般比OR操作符清單執(zhí)行更快。
- IN的最大優(yōu)點(diǎn)是可以包含其他SELECT語句瞳购,使得能夠更動(dòng)態(tài)地建立WHERE子句沉唠。
IN WHERE子句用來指定要匹配值的清單的關(guān)鍵字,功能與OR相當(dāng)
3. NOT操作符
? WHERE子句中的NOT操作符有且只有一個(gè)功能苛败,那就是否定它之后所跟的任何條件满葛。
NOT WHERE子句用來否定跟條件的關(guān)鍵字。
? 下面的例子說明NOT的使用罢屈。為了列出除1002和1003之外的所有供應(yīng)商制造的產(chǎn)品嘀韧,可編寫如下的代碼:
輸入:
SELECT prod_name,prod_price
FROM products
WHERE vend_id NOT IN (1002,1003)
ORDER BY prod_name;
輸出:
prod_name | prod_price |
---|---|
.5 ton anvil | 5.99 |
1 ton anvil | 9.99 |
2 ton anvil | 14.99 |
JetPack 1000 | 35.00 |
JetPack 2000 | 55.00 |
分析:
這里的NOT否定跟它之后的條件,因此缠捌,MySQL不是匹配1002和1003 的vend_id 锄贷,而是匹配1002和1003之外供應(yīng)商的vend_id译蒂。
? 為什么使用NOT?對(duì)于簡單的WHERE子句谊却,使用NOT確實(shí)沒有什么優(yōu)勢(shì)柔昼。但在更復(fù)雜的子句中,NOT是非常有用的炎辨。例如捕透,在與IN操作符聯(lián)合使用時(shí),NOT使找出與條件列表不匹配的行非常簡單碴萧。