概述
在實際的業務場景應用中,我們經常要根據業務條件獲取並篩選出我們的目標資料。這個過程我們稱之為資料查詢的過濾。而過濾過程使用的各種條件(比如日期時間、使用者、狀態)是我們獲取精準資料的必要步驟,
這樣才能得到我們期望的結果。所以本章我們來學習MySQL中查詢過濾條件的各種用法。
關係運算
關係運算就是where語句後跟上一個或者n個條件,滿足where後面條件的資料會被返回,反之不滿足的就會被過濾掉。operators指的是運算子 ,有如下幾種情況:
運算子 | 說明 |
= | 等於 |
<> 或者 != | 不等於 |
> | 大於 |
>= | 大於等於 |
< | 小於 |
<= | 小於等於 |
關係運算基本的語法格式如下:
1 select cname1,cname2,... from tname where cname operators cval
等於=
查詢出 列和後面的值嚴格相等的資料,非值型別的需要對後面值加上引號,值型別的不需要。
語法格式如下:
1 select cname1,cname2,... from tname where cname = cval;
1 mysql> select * from user2; 2 +----+-------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+-------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 +----+-------+-----+----------+-----+ 9 3 rows in set 10 11 mysql> select * from user2 where name='helen'; 12 +----+-------+-----+----------+-----+ 13 | id | name | age | address | sex | 14 +----+-------+-----+----------+-----+ 15 | 2 | helen | 20 | quanzhou | 0 | 16 +----+-------+-----+----------+-----+ 17 1 row in set 18 19 mysql> select * from user2 where age=21; 20 +----+-------+-----+---------+-----+ 21 | id | name | age | address | sex | 22 +----+-------+-----+---------+-----+ 23 | 1 | brand | 21 | fuzhou | 1 | 24 | 3 | sol | 21 | xiamen | 0 | 25 +----+-------+-----+---------+-----+ 26 2 rows in set
不等於(<>、!=)
不等於有兩種寫法,一種是<>,另一種是!=,意思一樣,可隨意切換使用,但是 <> 先於 != 出現,所以看很多以前的例子,<> 出現頻率比較高,可移植性更強,推薦使用。
不等於的目的是查詢出與條件不符和結果,格式如下:
select cname1,cname2,... from tname where cname <> cval; 或 select cname1,cname2,... from tname where cname != cval;
1 mysql> select * from user2; 2 +----+-------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+-------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 +----+-------+-----+----------+-----+ 9 3 rows in set 10 11 mysql> select * from user2 where age<>20; 12 +----+-------+-----+---------+-----+ 13 | id | name | age | address | sex | 14 +----+-------+-----+---------+-----+ 15 | 1 | brand | 21 | fuzhou | 1 | 16 | 3 | sol | 21 | xiamen | 0 | 17 +----+-------+-----+---------+-----+ 18 2 rows in set
大於小於(> <)
一般用於數值或者日期、時間型別的比較,格式如下:
1 select cname1,cname2,... from tname where cname > cval; 2 3 select cname1,cname2,... from tname where cname < cval; 4 5 select cname1,cname2,... from tname where cname >= cval; 6 7 select cname1,cname2,... from tname where cname <= cval;
1 mysql> select * from user2 where age>20; 2 +----+-------+-----+---------+-----+ 3 | id | name | age | address | sex | 4 +----+-------+-----+---------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 3 | sol | 21 | xiamen | 0 | 7 +----+-------+-----+---------+-----+ 8 2 rows in set 9 10 mysql> select * from user2 where age>=20; 11 +----+-------+-----+----------+-----+ 12 | id | name | age | address | sex | 13 +----+-------+-----+----------+-----+ 14 | 1 | brand | 21 | fuzhou | 1 | 15 | 2 | helen | 20 | quanzhou | 0 | 16 | 3 | sol | 21 | xiamen | 0 | 17 +----+-------+-----+----------+-----+ 18 3 rows in set 19 20 mysql> select * from user2 where age<21; 21 +----+-------+-----+----------+-----+ 22 | id | name | age | address | sex | 23 +----+-------+-----+----------+-----+ 24 | 2 | helen | 20 | quanzhou | 0 | 25 +----+-------+-----+----------+-----+ 26 1 row in set 27 28 mysql> select * from user2 where age<=21; 29 +----+-------+-----+----------+-----+ 30 | id | name | age | address | sex | 31 +----+-------+-----+----------+-----+ 32 | 1 | brand | 21 | fuzhou | 1 | 33 | 2 | helen | 20 | quanzhou | 0 | 34 | 3 | sol | 21 | xiamen | 0 | 35 +----+-------+-----+----------+-----+ 36 3 rows in set
邏輯運算
運算子 | 說明 |
---|---|
AND | 多個條件都成立 |
OR | 多個條件中滿足一個 |
NOT | 對條件進行取非操作 |
AND(且)
當需要多個條件進行資料過濾的時候,使用這種方式,and的每個表示式都是要成立,過濾出來的資料就是使用者需要的。
下面過濾出年齡和性別兩個條件都成立的資料,語法格式如下:
1 select cname1,cname2,... from tname where cname1 operators cval1 and cname2 operators cval2
1 mysql> select * from user2; 2 +----+-------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+-------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 | 4 | weng | 33 | guizhou | 1 | 9 +----+-------+-----+----------+-----+ 10 4 rows in set 11 12 mysql> select * from user2 where age >20 and sex=1; 13 +----+-------+-----+---------+-----+ 14 | id | name | age | address | sex | 15 +----+-------+-----+---------+-----+ 16 | 1 | brand | 21 | fuzhou | 1 | 17 | 4 | weng | 33 | guizhou | 1 | 18 +----+-------+-----+---------+-----+ 19 2 rows in set
OR(或)
當多個條件中只要滿足一個條件即進行資料過濾。
下面條件過濾出年齡大於21歲和小於21歲的資料,語法格式如下:
1 select cname1,cname2,... from tname where cname1 operators cval1 or cname2 operators cval2
1 mysql> select * from user2; 2 +----+-------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+-------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 | 4 | weng | 33 | guizhou | 1 | 9 +----+-------+-----+----------+-----+ 10 4 rows in set 11 12 mysql> select * from user2 where age>21 or age<21; 13 +----+-------+-----+----------+-----+ 14 | id | name | age | address | sex | 15 +----+-------+-----+----------+-----+ 16 | 2 | helen | 20 | quanzhou | 0 | 17 | 4 | weng | 33 | guizhou | 1 | 18 +----+-------+-----+----------+-----+ 19 2 rows in set
NOT(取非)
對某個滿足的條件進行取反,過濾出來的資料就是使用者需要的。
下面過濾不屬於年齡大於20的資料,語法格式如下:
1 select cname1,cname2,... from tname where not(cname operators cval)
1 mysql> select * from user2; 2 +----+-------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+-------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 | 4 | weng | 33 | guizhou | 1 | 9 +----+-------+-----+----------+-----+ 10 4 rows in set 11 12 mysql> select * from user2 where not(age>20); 13 +----+-------+-----+----------+-----+ 14 | id | name | age | address | sex | 15 +----+-------+-----+----------+-----+ 16 | 2 | helen | 20 | quanzhou | 0 | 17 +----+-------+-----+----------+-----+ 18 1 row in set
模糊匹配
就像我們上面的那個使用者表資訊表(包含名稱、年齡、地址、性別),當我們要查詢名稱為s開頭的使用者時,就可以用到 like 關鍵字了,他用以模糊匹配資料。
語法格式如下,pattern中可以包含萬用字元,有兩種。%:表示匹配任意一個或n個字元; _:表示匹配任意一個字元。
1 select cname1,cname2,... from tname where cname like pattern;
%的使用
1 mysql> select * from user2; 2 +----+--------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+--------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 | 4 | weng | 33 | guizhou | 1 | 9 | 5 | selina | 25 | taiwang | 0 | 10 +----+--------+-----+----------+-----+ 11 5 rows in set 12 13 mysql> select * from user2 where name like 's%'; 14 +----+--------+-----+---------+-----+ 15 | id | name | age | address | sex | 16 +----+--------+-----+---------+-----+ 17 | 3 | sol | 21 | xiamen | 0 | 18 | 5 | selina | 25 | taiwang | 0 | 19 +----+--------+-----+---------+-----+ 20 2 rows in set
_的使用
1 mysql> select * from user2; 2 +----+--------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+--------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 | 4 | weng | 33 | guizhou | 1 | 9 | 5 | selina | 25 | taiwang | 0 | 10 +----+--------+-----+----------+-----+ 11 5 rows in set 12 13 mysql> select * from user2 where name like 's_l'; 14 +----+------+-----+---------+-----+ 15 | id | name | age | address | sex | 16 +----+------+-----+---------+-----+ 17 | 3 | sol | 21 | xiamen | 0 | 18 +----+------+-----+---------+-----+ 19 1 row in set
注意點
1、不要過度使用模糊匹配得萬用字元。如果其他操作符能達到相同的目的,應該使用其他操作符
2、對大體量的表進行模糊匹配的時候儘量不要以%開頭,比如 like '%username',這樣會執行掃表,效率較慢。儘量明確模糊查詢的開頭部分,比如 like 'brand%',會先定位到brand開頭的資料,效率高很多。
範圍值檢查
BETWEEN AND(區間查詢)
操作符 BETWEEN … AND 會選取介於兩個值之間的資料範圍,這些值可以是數值、文字或者日期,屬於一個閉區間查詢。
and 的左邊val1 和 右邊 val2 分別表示兩個臨界值,等同於數學公式[val1,val2] ,屬於這兩個區間的資料會被過濾出來(>=val1 和 <=val2),所以語法格式如下:
1 selec cname1,cname2,... from tname where cname between val1 and val2; 2 等同於 3 selec cname1,cname2,... from tname where cname >= val1 and cname <= val2;
查詢年齡在[21,25]之間的資料:
1 mysql> select * from user2; 2 +----+--------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+--------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 | 4 | weng | 33 | guizhou | 1 | 9 | 5 | selina | 25 | taiwang | 0 | 10 +----+--------+-----+----------+-----+ 11 5 rows in set 12 13 mysql> select * from user2 where age between 21 and 25; 14 +----+--------+-----+---------+-----+ 15 | id | name | age | address | sex | 16 +----+--------+-----+---------+-----+ 17 | 1 | brand | 21 | fuzhou | 1 | 18 | 3 | sol | 21 | xiamen | 0 | 19 | 5 | selina | 25 | taiwang | 0 | 20 +----+--------+-----+---------+-----+ 21 3 rows in set 22 23 mysql> select * from user2 where age >= 21 and age <= 25; 24 +----+--------+-----+---------+-----+ 25 | id | name | age | address | sex | 26 +----+--------+-----+---------+-----+ 27 | 1 | brand | 21 | fuzhou | 1 | 28 | 3 | sol | 21 | xiamen | 0 | 29 | 5 | selina | 25 | taiwang | 0 | 30 +----+--------+-----+---------+-----+ 31 3 rows in set
IN(包含查詢)
按照上面得資料,如果我們想查出居住地位於福州和廈門得使用者資料,應該使用 IN操作符,因為 IN 操作符允許我們在 WHERE 子句中指定多個值,符合這些值中得某一項,既滿足條件返回資料。
語法格式如下,in 後面列表的值型別必須一致或相容,且不支援萬用字元:
1 select cname1,cname2,... from tname where cname in (val1,val2,...);
1 mysql> select * from user2; 2 +----+--------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+--------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 | 4 | weng | 33 | guizhou | 1 | 9 | 5 | selina | 25 | taiwang | 0 | 10 +----+--------+-----+----------+-----+ 11 5 rows in set 12 13 mysql> select * from user2 where address in('fuzhou','xiamen'); 14 +----+-------+-----+---------+-----+ 15 | id | name | age | address | sex | 16 +----+-------+-----+---------+-----+ 17 | 1 | brand | 21 | fuzhou | 1 | 18 | 3 | sol | 21 | xiamen | 0 | 19 +----+-------+-----+---------+-----+ 20 2 rows in set
NOT IN(對包含查詢取反)
我們上面已經學習過了not得使用者,對not後面執行得表示式進行取反得操作,測試下:
1 mysql> select * from user2; 2 +----+--------+-----+----------+-----+ 3 | id | name | age | address | sex | 4 +----+--------+-----+----------+-----+ 5 | 1 | brand | 21 | fuzhou | 1 | 6 | 2 | helen | 20 | quanzhou | 0 | 7 | 3 | sol | 21 | xiamen | 0 | 8 | 4 | weng | 33 | guizhou | 1 | 9 | 5 | selina | 25 | taiwang | 0 | 10 +----+--------+-----+----------+-----+ 11 5 rows in set 12 13 mysql> select * from user2 where address not in('fuzhou','quanzhou','xiamen'); 14 +----+--------+-----+---------+-----+ 15 | id | name | age | address | sex | 16 +----+--------+-----+---------+-----+ 17 | 4 | weng | 33 | guizhou | 1 | 18 | 5 | selina | 25 | taiwang | 0 | 19 +----+--------+-----+---------+-----+ 20 2 rows in set
空值檢查
IS NULL/IS NOT NULL
判斷是否為空,語法格式如下,這邊注意的是,對值為null的資料,各種比較運算子、like、between and、in、not in查詢都不起作用,只有is null 能夠過濾出來。
1 select cname1,cname2,... from tname where cname is null; 2 或者 3 select cname1,cname2,... from tname where cname is not null;
1 mysql> select * from user2 where address is null; 2 +----+--------+-----+---------+-----+ 3 | id | name | age | address | sex | 4 +----+--------+-----+---------+-----+ 5 | 5 | selina | 25 | NULL | 0 | 6 +----+--------+-----+---------+-----+ 7 1 row in set 8 9 mysql> select * from user2 where address is not null; 10 +----+-------+-----+----------+-----+ 11 | id | name | age | address | sex | 12 +----+-------+-----+----------+-----+ 13 | 1 | brand | 21 | fuzhou | 1 | 14 | 2 | helen | 20 | quanzhou | 0 | 15 | 3 | sol | 21 | xiamen | 0 | 16 | 4 | weng | 33 | guizhou | 1 | 17 +----+-------+-----+----------+-----+ 18 4 rows in set
有一種關鍵字 <=>,可以包含對null值得判斷,但是目前用的比較少了,有興趣可以去查查,這邊不贅述。
總結
1、like表示式中的%匹配一個到多個任意字元,_匹配一個任意字元
2、空值查詢需要使用IS NULL或者IS NOT NULL,其他查詢運算子對NULL值無效。即使%萬用字元可以匹配任何東西,也不能匹配值NULL的資料。
3、建議建立表的時候,表欄位不設定空,給欄位一個default 預設值。
4、MySQL支援使用NOT對IN 、BETWEEN 和EXISTS子句取反 。