1. 程式人生 > >MySQL全面瓦解7:查詢的過濾條件

MySQL全面瓦解7:查詢的過濾條件

概述

在實際的業務場景應用中,我們經常要根據業務條件獲取並篩選出我們的目標資料。這個過程我們稱之為資料查詢的過濾。而過濾過程使用的各種條件(比如日期時間、使用者、狀態)是我們獲取精準資料的必要步驟,

這樣才能得到我們期望的結果。所以本章我們來學習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子句取反 。

 <