6-使用通配符進行過濾
6.1-LIKE操作符
前面介紹的所有操作符都是通過已知的值進行過濾,或者檢查某個范圍的值。但是如果我們想要查找產品名字中含有bag的數據,就不能使用前面那種過濾情況。
利用通配符,可以創建比較特定數據的搜索模式。
搜索模式:由字面值、通配符或兩者組合構成的搜索條件。
通配符實際上是SQL語句中where子句中具有特殊含義的字符,SQL支持幾種通配符。在為搜索子句中使用通配符,必須使用like操作符。
謂詞:操作符何時不是操作符?答案是,它作為謂詞時。從技術上說,LIKE是謂詞而不是操作符。
通配符搜索只能用于文本字段(字符串),非文本數據類型字段不能使用通配符搜索。
6.1.1 百分號(%)通配符
百分號是最常用的通配符,%表示任何字符出現任意次數。
select prod_id,prod_name
from products
where prod_name LIKE 'Fish%';
上述SQL語句的含義是,查找名稱以‘Fish’開頭的行。執行上述語句時,會檢索所有以'Fish'開頭的詞,不管它有多少字符。
一般來說,根據DBMS不同的配置,可以是區分大小寫,'Fish'和‘fish’相同。也可以是不區分大小寫,'Fish'和‘fish’不同。
通配符可以在搜索模式任意位置使用,并且可以使用多個通配符。
select prod_id,prod_name
from products
where prod_name LIKE '%bean bag%';
?
上述語句檢索的數據特征是:名字中含有bean bag這段字符串的數據,不管它之前或者之后出現什么樣的字符串。
通配符還可以出現搜索模式的中間,雖然這么做不太有用。下面例子找出以F開頭,以y結尾的數據。
select prod_id,prod_name
from products
where prod_name LIKE 'F%y';
?
有一種情況把通配符放到搜索模式的中間,是很有效果的,就是根據郵件地址的一部分查找郵件。例如WHERE email LIKE 'b%@forta.com'
。
注意:除了能匹配一個或多個字符以外,%還可以匹配0個字符。%代表搜索模式中給定位置的0個、1個或多個字符。
通配符%看起來像是可以匹配任何東西,但有個例外,這就是NULL。子句WHERE prod_name LIKE '%'不會匹配產品名稱為NULL的行。
6.1.2 下劃線(_)通配符
作用與%通配符相同,只不過,它只匹配單個字符,并不會匹配多個字符。
select prod_id,prod_name
from products
where prod_name LIKE '__ inch teddy bear';
上述代碼,給出了兩個下劃線通配符,檢索出的數據應該是開頭兩個字符的數據。因此,產品名為“8 inch teddy bear”的產品不會被檢索到。
6.1.3 方括號([ ])通配符
方括號通配符是指定一個字符集,它必須匹配指定位置(通配符的位置)的一個字符。
并不是所有DBMS都支持用來創建集合的[]。微軟的SQL Server支持集合,但是MySQL,Oracle,DB2,SQLite都不支持。
SELECT cust_contact
FROM Customers
WHERE cust_contact LIKE '[JM]%'
ORDER BY cust_contact;
名字以J或M起頭的聯系人。
此語句的WHERE子句中的模式為'[JM]%'。這一搜索模式使用了兩個不同的通配符。[JM]匹配方括號中任意一個字符,它也只能匹配單個字符。因此,任何多于一個字符的名字都不匹配。[JM]之后的%通配符匹配第一個字符之后的任意數目的字符,返回所需結果。
此通配符可以用前綴字符^(脫字號)來否定。例如,下面的查詢匹配以J和M之外的任意字符起頭的任意聯系人名。
SELECT cust_contact
FROM Customers
WHERE cust_contact LIKE '[^JM]%'
ORDER BY cust_contact;
也可以使用NOT操作符得出類似的結果。^的唯一優點是在使用多個WHERE子句時可以簡化語法
SELECT cust_contact
FROM Customers
WHERE NOT cust_contact LIKE '[JM]%'
ORDER BY cust_contact;
6.2-使用通配符技巧
SQL通配符很有用,但是這種功能也是有代價的,相較于其他檢索來說,通配符更耗費時間。
技巧:
-
不要過度使用通配符。如果其他操作符能達到相同目的,應該以其他操作符為主。
-
在確實需要使用通配符的時候,也不要把通配符使用在開始處。把通配符置于開始處是速度最慢的。
-
注意通配符的位置,如果位置不對,則返回的結果可能不盡如人意。