谓词,通常来说是函数的一种,是需要满足特定条件的函数。该条件就是“返回值是真值”,即返回的值必须为TRUE/FALSE/UNKNOWN。
1.LIKE谓词—字符串的部分一致查询
截至目前,字符串的查询都是用"="进行查询,也就是只有在"="两侧完全一致时才能为真。与之相反,LIKE谓词更加模糊,即字符串部分一致也为真。
首先创建一张名为SampleLike的表,如下:
+---------+
| str_exp |
+---------+
| abcddd |
| dddabc |
| abddc |
| abcdd |
| ddabc |
| abddc |
+---------+
前方一致查询
SELECT *
FROM SampleLike
WHERE str_exp LIKE 'ddd%';
+---------+
| str_exp |
+---------+
| dddabc |
+---------+
其中"%"代表"0字符以上的任意字符串"的特殊符号。
中间一致查询
SELECT *
FROM SampleLike
WHERE str_exp LIKE '%ddd%';
+---------+
| str_exp |
+---------+
| abcddd |
| dddabc |
+---------+
在字符串的起始和末尾都加上"%",就能取出包含"ddd"的字符串了。
后方一致查询
SELECT *
FROM SampleLike
WHERE str_exp LIKE '%ddd';
+---------+
| str_exp |
+---------+
| abcddd |
+---------+
使用"_"选取字符
此外,我们还可以用"_(下划线)"代替"%",与"%"不同的是其代表了"任意一个字符"。
--使用__(下划线)进行后方一致查询
SELECT *
FROM SampleLike
WHERE str_exp LIKE 'abc__';
+---------+
| str_exp |
+---------+
| abcdd |
+---------+
--查询"abc+任意3个字符"的字符串
SELECT *
FROM SampleLike
WHERE str_exp LIKE 'abc___';
+---------+
| str_exp |
+---------+
| abcddd |
+---------+
LIKE查询通配符:
1.%:表示任意 0 个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。
2._:表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句。
3.[]:表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。
4.[^] :表示不在括号所列之内的单个字符。其取值和 [] 相同,但它要求所匹配对象为指定字符以外的任一个字符。
5.查询内容包含通配符时,由于通配符的缘故,导致我们查询特殊字符 “%”、“_”、“[” 的语句无法正常实现,而把特殊字符用 “[ ]” 括起便可正常查询。
2.BETWEEN谓词—范围查询
使用BETWEEN可以进行范围查询。该谓词与其他谓词或者函数的不同之处在于它使用了3个参数。
SELECT shop_name,sell_price
FROM shop_list
WHERE sell_price BETWEEN 1000 AND 3000;
使用BETWEEN会包含两个临界值,如果不想让结果包含临界值,那么就必须用"<"和">"。
3.IS NULL、IS NOT NULL —判断是否为NULL
为了选取某些值为NULL的列的数据,不能使用"=",而只能使用特定的谓词IS NULL。
SELECT <列名>
FROM <表名>
WHERE <列名> IS NULL;
4.IN 谓词—OR的简便用法
使用OR子句可以选择多个数据进行抽取,如下:
SELECT <列1>,<列2>····
FROM <表名>
WHERE <列名> = <数据1>
OR <列名> = <数据2>
OR <列名> = <数据3>;
如果使用IN 谓词,那么以上的写法可以更加简单:
SELECT <列1>,<列2>····
FROM <表名>
WHERE <列名> IN (数据1,数据2,数据3);
需要注意的是,使用IN和NOT IN 的时候是不能取出NULL的数据的。
使用子查询作为IN谓词的参数
IN和子查询
IN和NOT IN具有其他谓词没有的用法,那就是可以使用子查询作为其参数来使用。
为了方便演示,创建一张名称为shop_ares的表,如下:
+---------+-----------+---------+--------+
| area_id | area_name | shop_id | number |
+---------+-----------+---------+--------+
| 000A | 北京 | 0001 | 30 |
| 000A | 北京 | 0002 | 50 |
| 000A | 北京 | 0003 | 15 |
| 000B | 上海 | 0002 | 30 |
| 000B | 上海 | 0003 | 120 |
| 000B | 上海 | 0004 | 20 |
| 000B | 上海 | 0006 | 10 |
| 000B | 上海 | 0007 | 40 |
| 000C | 重庆 | 0003 | 20 |
| 000C | 重庆 | 0004 | 50 |
| 000C | 重庆 | 0006 | 90 |
| 000C | 重庆 | 0007 | 70 |
| 000D | 杭州 | 0001 | 100 |
+---------+-----------+---------+--------+
如果我们想要选出000B地区商品的数据,那么需要两个步骤:
1.首先选出根据area_id选出所有000B地区的数据;
SELECT *
FROM shop_area
WHERE area_id='000B';
+---------+-----------+---------+--------+
| area_id | area_name | shop_id | number |
+---------+-----------+---------+--------+
| 000B | 上海 | 0002 | 30 |
| 000B | 上海 | 0003 | 120 |
| 000B | 上海 | 0004 | 20 |
| 000B | 上海 | 0006 | 10 |
| 000B | 上海 | 0007 | 40 |
+---------+-----------+---------+--------+
2.使用子查询作为IN的参数读取000B的商品数据;
SELECT shop_id,shop_name,sell_price
FROM shop_list
WHERE shop_id IN (SELECT shop_id FROM shop_area WHERE area_id='000B');
+---------+-----------+------------+
| shop_id | shop_name | sell_price |
+---------+-----------+------------+
| 0002 | 打孔器 | 600 |
| 0003 | 运动T恤 | 3000 |
| 0004 | 菜刀 | 6000 |
| 0006 | 扳手 | 3000 |
+---------+-----------+------------+
使用IN的好处在于:数据不是一成不变的,当数据发生变化时,子查询语句查询的值也发生了变换,不像"="总是一个固定的值。
NOT IN也可以使用子查询作为参数,其语法和IN完全一样。
5.EXIST谓词
EXIST的左侧没有参数,因为EXIST是只有一个参数的谓词,所以只需要在右侧写一个参数,该参数通常都是一个子查询(通常指定关联子查询作为EXIST的参数)。
SELECT shop_name,sell_price
FROM shop_list as SL
WHERE EXISTS (SELECT *
FROM shop_area AS SA
WHERE SA.area_id='000b'
AND SA.shop_id=SL.shop_id);
+-----------+------------+
| shop_name | sell_price |
+-----------+------------+
| 打孔器 | 600 |
| 运动T恤 | 3000 |
| 菜刀 | 6000 |
| 扳手 | 3000 |
+-----------+------------+
EXIST的参数
EXIST的左侧没有参数,因为EXIST是只有一个参数的谓词,所以只需要在右侧写一个参数,该参数通常都是一个子查询(通常指定关联子查询作为EXIST的参数)。
使用 NOT EXITS 代替NOT IN
以下示例(读取上海地区000B在售以外商品的单价):
SELECT shop_name,sell_price
FROM shop_list AS SL
WHERE NOT EXISTS(SELECT*
FROM shop_area AS SA
WHERE SA.area_id='000B'
AND SA.shop_id=SL.shop_id);
+-----------+------------+
| shop_name | sell_price |
+-----------+------------+
| T恤衫 | 2000 |
| 砧板 | 2000 |
+-----------+------------+