04-06章 过滤数据

第4章 过滤数据

4.1 WHERE 子句

根据需要提取表数据的子集,需要指定搜索条件(search criteria)。

  • 在 SELECT 语句中,数据根据 WHERE 子句中指定的搜索条件进行过滤。
  • WHERE 子句在表名(FROM 子句)之后给出。
SELECT prod_name, prod_price FROM Products
WHERE prod_price = 3.49;

分析
这条语句从 products 表中检索两个列,但不返回所有行,只返回 prod_price 值为 3.49 的行,输出:

屏幕快照 2018-05-27 08.32.33.png

注意
同时使用 ORDER BY 和 WHERE 子句时,ORDER BY 应位于 WHERE 之后,否则将出错。

4.2 WHERE 子句操作符

操作符 说明 操作符 说明
= 等于 > 大于
<> 不等于 >= 大于等于
!= 不等于 !> 不大于
< 小于 BETWEEN 在指定的两个值之间
<= 小于等于 IS NULL 为NULL值
!< 不小于

检查单个值
列出所有价格小于等于 10 美元的产品。

SELECT prod_name, prod_price FROM Products
WHERE prod_price <= 10;
屏幕快照 2018-05-27 08.52.12.png

不匹配检查
列出所有不是供应商 DLL01 制造的产品:

SELECT vend_id, prod_name FROM Products
WHERE vend_id <> 'DLL01';
屏幕快照 2018-05-27 08.56.58.png

注意:何时使用引号
上述 WHERE 子句中的条件,有的值括在单引号内,而有的值未括起来。

  • 单引号用来限定字符串。
  • 将值与字符串类型的列进行比较,就要限定引号。
  • 将值与数值列进行比较,不用引号。

范围值检索
要检查某个范围的值,使用 BETWEEN 操作符。其语法与其他 WHERE 子句的操作符稍有不同,因为它需要两个值,即范围的开始值和结束值。

例如,BETWEEN 操作符可用来检索价格在 5 美元和 10 美元之间的所有产品,或在指定的开始日期和结束日期之间的所有日期。

SELECT prod_name, prod_price FROM Products
WHERE prod_price BETWEEN 5 AND 10;
屏幕快照 2018-05-27 10.51.33.png

空值检查
在创建表时,表设计人员可以指定其中的列能否不包含值。在一个列不包含值时,称其包含空值 NULL。确定值是否为 NULL,用 IS NULL 子句。

SELECT prod_name FROM Products
WHERE prod_price IS NULL;

这条语句返回所有没有价格(空 prod_price 字段,不是价格为 0)的产品。
但是,Customers 表包含具有 NULL 值的列:如果没有电子邮件地址,则 cust_email 列将包含 NULL 值:

SELECT cust_name FROM Customers
WHERE cust_email IS NULL;
屏幕快照 2018-05-27 10.58.20.png

第5章 高级数据过滤

5.1 组合 WHERE 子句

SQL 允许给出多个 WHERE 子句,这些子句有两种使用方式,即以 AND 子句或 OR 子句的方式使用。

AND 操作符

SELECT prod_id, prod_price, prod_name FROM Products
WHERE vend_id = 'DLL01' AND prod_price <= 4;

此 SQL 语句检索由供应商 DLL01 制造且价格小于等于 4 美元的所有产品的名称和价格。


屏幕快照 2018-05-27 11.03.13.png

OR 操作符
许多 DBMS 在 OR WHERE 子句的第一个条件得到满足的情况下,就不再计算第二个条件了(在第一个条件满足时,不管第二个条件是否满足,相应的行都将被检索出来)。

SELECT prod_name, prod_price FROM Products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';
屏幕快照 2018-05-27 11.06.50.png

求值顺序
需要列出价格为10美元及以上,且由 DLL01 或 BRS01 制造的所有产品。

SELECT prod_name, prod_price FROM Products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01'
      AND prod_price >= 10;
屏幕快照 2018-05-27 11.11.10.png

上面结果返回的行中有 4 行价格小于 10 美元,原因在于求值的顺序。

  • SQL 在处理 OR 操作符前,优先处理 AND 操作符。
  • SQL 理解 WHERE 子句为:由供应商 BRS01 制造的价格为 10 美元以上的所有产品,以及由供应商 DLL01 制造的所有产品,而不管其价格如何。
  • 由于 AND 在求值过程中优先级更高,操作符被错误地组合。

此问题的解决方法是使用圆括号对操作符进行明确分组:

SELECT prod_name, prod_price FROM Products
WHERE (vend_id = 'DLL01' OR vend_id= 'BRS01')
      AND prod_price >= 10;
屏幕快照 2018-05-27 11.17.33.png

将前两个条件用圆括号括起来,因为圆括号具有比 AND 或 OR 操作符更高的求值顺序,所以 DBMS 首先过滤圆括号内的 OR 条件。

注意
任何时候使用具有 AND 和 OR 操作符的 WHERE 子句,都要使用圆括号分组操作符。

5.2 IN 操作符

IN 操作符用来指定条件范围,一组由逗号分隔括在圆括号中的合法值,范围中的每个条件都可以进行匹配,与 OR 功能相同。

SELECT prod_name, prod_price FROM Products
WHERE vend_id IN ('DLL01', 'BRS01')
ORDER BY prod_name;
屏幕快照 2018-05-27 11.26.02.png

IN 操作符的优点

  • IN 操作符的语法更清楚直观。
  • 在与其他 AND 和 OR 操作符组合使用 IN 时,求值顺序更容易管理。
  • IN 操作符一般比一组 OR 操作符执行得更快。
  • IN 可以包含其他 SELECT 语句, 能够更动态地建立 WHERE 子句。

5.3 NOT 操作符

WHERE 子句中的 NOT 操作符只有一个功能,否定其后所跟的任何条件。列出除 DLL01 之外的所有供应商制造的产品:

SELECT prod_name FROM Products
WHERE NOT vend_id= 'DLL01' ORDER BY prod_name;
屏幕快照 2018-05-27 11.32.56.png

第6章 用通配符进行过滤

6.1 LIKE 操作符

通配符(wildcard)用来匹配值的一部分的特殊字符。
搜索模式(search pattern)由字面值、通配符或两者组合构成的搜索条件。

通配符实际上是 SQL 的 WHERE 子句中有特殊含义的字符。为在搜索子句中使用通配符,必须使用 LIKE 操作符。LIKE 指示 DBMS,后跟的搜索模式利用通配符匹配而不是简单的相等匹配进行比较。

百分号(%)通配符
在搜索串中,%表示任何字符出现任意次数。要找出所有以词 Fish 开头的产品:

SELECT prod_id, prod_name FROM Products
WHERE prod_name LIKE 'Fish%'
屏幕快照 2018-05-27 12.25.46.png

在执行这条子句时,将检索任意以 Fish 起头的词。%告诉 DBMS 接受 Fish 之后的任意字符,不管它有多少字符。

通配符可在搜索模式中的任意位置使用,并且可以使用多个通配符。例子使用两个通配符,它们位于模式的两端:

SELECT prod_id, prod_name FROM Products
WHERE prod_name LIKE '%bean bag%';
屏幕快照 2018-05-27 12.30.15.png

注意
包括 Access 在内的许多 DBMS 都用空格来填补字段的内容。
例如,如果某列有 50 个字符,而存储的文本为 Fish bean bag toy(17 个字符),则为填满该列需要在文本后附加 33 个空格。这样做一般对数据及其使用没有影响,但是可能对上述 SQL语句有负面影响。

子句WHERE prod_name LIKE 'F%y'只匹配以 F 开头以 y 结尾的 prod_name。如果值后面跟空格,则不是以 y 结尾,所以 Fish bean bag toy 就不会检索出来。

解决办法:给搜索模式再增加一个%号,'F%y%'还匹配 y 之后的字符或空格。

注意
通配符%不能匹配 NULL,子句WHERE prod_name LIKE '%'不匹配产品名称为 NULL 的行。

下划线(_)通配符
下划线的用途与%一样,但只匹配单个字符,而不是多个字符。

SELECT prod_id, prod_name FROM Products
WHERE prod_name LIKE '__ inch teddy bear';
屏幕快照 2018-05-27 12.40.46.png

下面 SELECT 语句使用%通配符,返回三行产品:

SELECT prod_id, prod_name FROM Products
WHERE prod_name LIKE '% inch teddy bear';
屏幕快照 2018-05-27 12.43.25.png

方括号([ ])通配符
方括号([])通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符。目前只有 Access 和 SQL Server 支持集合。

例如找出所有名字以 J 或 M 起头的联系人:

SELECT cust_contact FROM Customers
WHERE cust_contact LIKE '[JM]%' ORDER BY cust_contact;
屏幕快照 2018-05-27 12.49.26.png

此语句的 WHERE 子句中的模式为'[JM]%',这一搜索模式使用了两个不同的通配符。[JM]匹配方括号中任意一个字符,它也只能匹配单个字符。

此通配符可以用前缀字符(脱字号)来否定。例如,查询以 J 和 M 之外的任意字符起头的任意联系人名:

SELECT cust_contact FROM Customers
WHERE cust_contact LIKE '[^JM]%' ORDER BY cust_contact;

也可以使用 NOT 操作符得出类似的结果:

SELECT cust_contact FROM Customers
WHERE NOT cust_contact LIKE '[JM]%' ORDER BY cust_contact;

6.2 使用通配符的技巧

  1. 如果其他操作符能达到相同的目的,应该使用其他操作符。
  2. 确实需要使用通配符时,不要把它们用在搜索模式的开始处,会非常慢。
  3. 如果通配符放错地方,不会返回想要的数据。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容