【SQL必知必会笔记(3)】SELECT语句的WHERE子句数据过滤操作
上个笔记主要介绍了利用SELECT语句检索单个/多个/所有列,并利用DISTINCT关键字检索具有唯一性的值、利用LIMIT/OFFSET子句限制结果;以及利用ORDER BY子句排序检索出的数据,主要有按照单个/多个列名/列位置/混合排序、用DESC关键字指定排序方向。
这一次我们来看一下如何使用SELECT语句的WHERE子句来指定搜索条件进行数据过滤,包括使用=、>、<等基础操作符的基础数据过滤;使用AND、OR、IN、NOT操作符的高级数据过滤;以及使用%、_、[]通配符的数据过滤操作,以及实际使用中的一些细节。
文章目录
1.过滤数据(WHERE子句)
数据库表一般包含大量的数据,很少需要检索表中的所有行。通常只会根据特定操作或报告的需要提取表数据的子集。
只检索所需数据需要指定搜索条件(search criteria),或称为过滤条件(filter condition)。
- 在SELECT语句中,数据根据WHERE子句中指定的过滤条件进行过滤。
- WHERE子句位置:在表名(FROM子句)之后给出。
- 通过非选择列进行过滤。用非检索的列过滤数据也是是完全合法的。
1.1 WHERE子句操作符
- 注意:操作符兼容。表中所列出的操作符是冗余的,有功能相同的操作符。具体DBMS支持的操作符不一样。
- 经过尝试,MySQL中除不支持!<、!>这两个操作符外,其他都支持。
- SQL过滤 or 在应用层过滤?通常最好选择SQL过滤。
1.2 过滤操作
1.2.1 检查单个值
- 语句:
SELECT 列名1,列名2
FROM 表
WHERE 列名1 < 10;
1.2.2 不匹配检查(!=、<>操作符)
- 语句:
SELECT 列名1,列名2
FROM 表
WHERE 列名1 <> 'DLL01';
提示:
- 单引号用来限定字符串。若将值与字符串类型的列进行比较,就需要限定引号;若将值与数值列进行比较,则不用引号。
1.2.3 范围值检查(BETWEEN操作符)
- 语句:
SELECT 列名1,列名2
FROM 表
WHERE 列名1 BETWEEN 5 AND 10;
提示:
- 在使用BETWEEN操作符时,必须指定两个值:所需范围的低端值和高端值。(闭区间)
- 并且这两个值必须用AND关键字分隔。
1.2.4 空值检查(IS NULL操作符)
- 语句:
SELECT 列名1,列名2
FROM 表
WHERE 列名1 IS NULL;
分析:
- 在创建表时,表设计人员可以指定其中的列能否不包含值。在一个列不包含值时,称其包含空值NULL。
- NULL:无值(no value),它与字段包含0、空字符串或仅仅包含空格不同。
提示:各DBMS 特有的操作符。
- 许多DBMS 扩展了标准操作符集,提供了更高级的过滤选择,想了解可以参阅相应DBMS文档。
注意:NULL和非匹配。
- 在进行匹配过滤或非匹配过滤时,不会返回含NULL值的行。
- 因此过滤数据时,一定要验证被过滤列中含NULL值的行确实出现在返回的数据中。
2.高级数据过滤(组合WHERE子句)
在上一小节中,所有的WHERE子句在过滤数据时使用的都是单一的条件。为了进行更强的过滤控制,SQL允许给出多个WHERE子句。这些句子有两种使用方式:以AND子句或OR子句的方式使用。
- 操作符(operator):用来联结或改变 WHERE子句中的//子句//的关键字,也称为逻辑操作符(logical operator)。
下面我们就来分别介绍一下AND、OR、IN、NOT四种操作符。
2.1 AND操作符
要通过不止一个列进行过滤,可以使用AND操作符给WHERE子句附加条件。
- 语句:
SELECT 列名1,列名2,列名3
FROM 表
WHERE 列名1 = 值1 AND 列名2 <= 值2;
分析:
- AND:用在WHERE子句中的关键字,用来表示//检索(v)//满足所有给定条件的行。
- 这个例子中只有两个过滤条件。可以增加多个过滤条件,每个条件间都要使用AND关键字。
注意:
- 例子中省略了ORDER BY子句。因此不同情况下做出来的输出,顺序可能不同。可以在WHERE子句之后加上一个ORDER BY子句。
2.2 OR操作符
- 语句:
SELECT 列名1,列名2,列名3
FROM 表
WHERE 列名1 = 值1 OR 列名2 = 值2;
分析:
- OR:用在WHERE子句中的关键字,用来表示//检索(v)//满足任一给定条件的行。(可以看出,OR的功能与AND正好相反。)
提示:
- 许多DBMS在OR WHERE子句的第一个条件得到满足时,不管第二个条件是否满足,相应的行都将被检索出来。
2.3 求值顺序(AND与OR结合时)
WHERE子句可以包含任意数目的AND和OR操作符。允许两者结合进行复杂、高级的过滤。
提示:在结合 AND和OR时,要注意求值的顺序(优先级):
- SQL(像多数语言一样)在处理OR操作符前,优先处理AND操作符。
- 优先级:圆括号 > AND > OR。在三者中圆括号的优先级最高。
- 任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确地分组操作符。
2.4 IN操作符
- 语句:
SELECT 列名1,列名2,列名3
FROM 表
WHERE 列名1 IN (值1,值2)
ORDER BY 列名2;
分析:
IN后跟一组由逗号分隔,括在圆括号(必须)中的合法值。
IN操作符用来指定条件范围,范围中的//每个条件都可以进行匹配。功能与OR相当,下面看一个实例:
语句1:
SELECT prod_name,prod_price
FROM Products
WHERE vend_id IN ('DLL01','BRS01')
ORDER BY prod_name; 语句2:
SELECT prod_name,prod_price
FROM Products
WHERE vend_id ='DLL01' OR vend_id = 'BRS01'
ORDER BY prod_name; 语句1与语句2输出完全一样。
注意:使用OR时,即使检索同一个列的不同值,也不可以直接:vend_id ='DLL01' OR 'BRS01'
那么,既然IN与OR功能相当,我们为什么还要使用IN操作符呢?IN操作符的优点如下:
- 语法更清楚、直观;
- 在与其他AND和OR操作符组合使用IN时,求值顺序更容易管理;
- IN操作符一般比一组OR操作符执行得更快。
- 最大优点:IN操作符可以包含其他SELECT语句,能够更动态地建立WHERE子句。(后续的笔记中,还会对此做详细介绍。)
2.5 NOT操作符
- 语句:
SELECT 列名1
FROM 表
WHERE NOT 列名1 = 值1
ORDER BY 列名1;
上面这个例子也可以使用<>或!=操作符来完成。
分析:
- NOT操作符:有且只有一个功能,即否定其后所跟的任何条件。
- NOT 从不单独使用,所以它的语法与其他操作符有所不同。可以用在要过滤的列前 ,也可以用在要过滤的列后。
说明:
- 大多数DBMS:允许使用NOT否定任何条件。
- MariaDB:支持使用NOT否定IN、BETWEEN和EXISTS子句。
NOT的优点:
- 对于上面例子中简单的WHERE子句,使用NOT确实没有什么优势。
- 但是在更复杂的子句中,NOT是非常有用的。比如,在与IN操作符联合使用时,NOT可以非常简单地找出与条件列表不匹配的行。
3.用通配符进行过滤(LIKE + 通配符)
前面所介绍的所有操作符都是针对已知(完整)值进行过滤的。但是这种过滤方法并不是任何时候都好用。有些时候需要利用通配符,来创建(v)//用于比较(v)特定数据的//搜索模式。
- 通配符(wildcard):用来匹配值的一部分的特殊字符。
- 搜索模式(search pattern):由字面值(已知值)、通配符或两者组合构成的搜索条件。
通配符本身实际上是SQL的WHERE子句中有特殊含义的字符,SQL支持几种通配符。
LIKE操作符:
- 为在搜索句子中使用通配符,必须使用LIKE操作符。
- LIKE指示DBMS,后跟的搜索模式利用通配符匹配,而不是简单的相等匹配进行比较。
注意:
- 通配符搜索,只能用于文本字段(字符串),非文本数据类型字段不能使用通配符搜索。
谓词(predicate)(选看):
- 操作符何时不是操作符?答案是,它作为谓词时。
- 从技术上说,LIKE是谓词而不是操作符。虽然最终的结果是相同的,但应对此术语有所了解,以免在SQL文献或手册中遇到此术语时不知所云。
3.1 百分号(%)通配符
语句:
SELECT 列名1,列名2,列名3
FROM 表
WHERE 列名1 LIKE 'Fish%';
分析:
- %是最常用的通配符。
- 在搜索串中,%表示任何字符(除NULL)出现任意次数(包括0次)。
- 通配符(不止是%)可以在搜索模式中的任意位置使用,并且可以使用多个通配符。
说明:
- Access通配符。如果使用的是Microsoft Access,需要使用*而不是%。
- 区分大小写。根据DBMS的不同及其配置,搜索可以是区分大小写的。
注意:
注意字符串后面所跟的空格,包括Access在内的许多DBMS都用空格来填补字段的内容。(经过测试,默认设置的MySQL中没有填补空格的机制。)
例如,如果某列有50个字符,而存储的文本为Fish bean bag toy(17个字符),则为填满该列需要在文本后附加33个空格。
这样做一般对数据及其使用没有影响,但是可能对某些SQL语句有负面影响。
例如,子句WHERE prod_name LIKE 'F%y'只匹配以F开头,以y结尾的prod_name。如果值后面跟空格,则不是以y结尾,那么最终检索结果就不是我们预想的。 - 解决办法:简单的,给搜索模式再增加一个%,即'F%y%';
更好的解决办法,用函数去掉空格(后面详细介绍)
注意NULL。通配符%无法匹配NULL。
3.2 下划线(_)通配符
- 语句:
SELECT 列名1,列名2
FROM 表
WHERE 列名1 LIKE '__ inch teddy bear';
分析:
- -总是刚好匹配一个字符,不能多也不能少。
- %可以匹配0个、1个、多个字符。
说明:
- DB2不支持通配符_
- Access通配符。如果使用的是Microsoft Access,需要使用?而不是_。
3.3 方括号([])通配符(MySQL不支持)
- 语句:
SELECT 列名1
FROM 表
WHERE 列名1 LIKE '[JM]%'
ORDER BY 列名1;
分析:
- []通配符用来指定一个字符集,它必须(也只能)匹配指定位置(通配符的位置)的一个字符。
- 此通配符可以用前缀字符(脱字号^)来否定。也可以使用NOT操作符得到类似的结果
,^的唯一优点是在使用多个WHERE子句时可以简化语法。
说明:
- 并不总是支持集合。与前面描述的通配符不一样,并不是所有DBMS都支持用来创建集合的[]。只有Access和SQL Server支持集合。(经过测试,MySQL确实不支持这个操作。)
- Access中需要用!而不是^来否定一个集合。即,用[!JM],而不是[ ^JM]。
3.4 使用通配符的技巧
正如本节我们介绍,SQL的通配符很拥有。但是这种功能是有代价的,即通配符搜索一般比前面讨论的其他搜索要耗费更长的处理时间。
使用通配符的技巧:
- 不要过度使用通配符。其他操作符能达到相同的目的,尽量使用其他操作符。
- 确实需要使用通配符时,尽量不要把它们放在搜索模式的开始处。
- 仔细注意通配符的位置。如果放错地方,可能不会返回我们想要的数据。
总之,通配符是一种极其重要和有用的搜索工具,以后我们经常会用到它。
参考资料:
1.《SQL必知必会》Ben Forta。
【SQL必知必会笔记(3)】SELECT语句的WHERE子句数据过滤操作的更多相关文章
- 读书笔记汇总 - SQL必知必会(第4版)
本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...
- 读书笔记--SQL必知必会18--视图
读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...
- 《SQL必知必会》学习笔记二)
<SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...
- SQL必知必会 -------- SELECT、注释
主要是看<SQL必知必会>第四版的书,而写的一些SQL笔记,红色的是方便以后查询的sql语句,工作中主要是使用mysql数据库,所以笔记也是围绕mysql而写的. 下文调试的数据表sql语 ...
- 【SQL必知必会笔记(2)】检索数据、排序检索数据
上个笔记中介绍了一些关于数据库.SQL的基础知识,并且创建我们后续练习所需的数据库.表以及表之间的关系,从本文开始进入我们的正题:SQL语句的练习. 文章目录 1.检索数据(SELECT语句) 1.1 ...
- 读书笔记--SQL必知必会--建立练习环境
书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL in 10 Minutes - Fourth Edition> MyS ...
- 读书笔记--SQL必知必会12--联结表
12.1 联结 联结(join),利用SQL的SELECT在数据查询的执行中联结表. 12.1.1 关系表 关系数据库中,关系表的设计是把信息分解成多个表,一类数据一个表,各表通过某些共同的值互相关联 ...
- 《SQL必知必会》学习笔记(一)
这两天看了<SQL必知必会>第四版这本书,并照着书上做了不少实验,也对以前的概念有得新的认识,也发现以前自己有得地方理解错了.我采用的数据库是SQL Server2012.数据库中有一张比 ...
- 0005 《SQL必知必会》笔记01-SELECT语句
1.SELECT基本语句: SELECT 字段名1,···,字段名n FROM 表名 2.检索所有字段,用"*"替换字段名,这会导致效率低下 SELECT * FROM 表名; 3 ...
随机推荐
- 面试官:说说Spring中的事务传播行为
前言 在开发中,相信大家都使用过Spring的事务管理功能.那么,你是否有了解过,Spring的事务传播行为呢? Spring中,有7种类型的事务传播行为.事务传播行为是Spring框架提供的一种事务 ...
- SQL的四种连接(内连接,外连接)
一,内连接(inner join) 内连接(INNER JOIN):分显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行.(所谓的连接表就是数据库在做查询形成的中间表). 1.隐式的内连接 没 ...
- spring boot中的底层配置文件application.yam(application.property)的装配原理初探
*在spring boot中有一个基础的配置文件application.yam(application.property)用于对spring boot的默认设置做一些改动. *在spring boot ...
- 对象和Map转化gongju
package czc.superzig.modular.utils; import java.lang.reflect.Field; import java.util.HashMap; import ...
- .NET精彩博文
vs2019安装和使用教程(详细) 为什么选择.NETCore? C#中Socket的简单使用
- C语言入门---第九章 C语言指针
没学指针就是没学C语言! 指针是C语言的精华,也是C语言的难点. 所谓指针,也就是内存的地址,所谓指针变量,也就是保存了内存地址的变量.不过人们往往不会区分两者的概念,而是混淆在一起使用. ===== ...
- 解题报告:luogu P2220
指挥使走后一脸懵逼,然后想起了一道水\(SB\)的省选题. 这是毒瘤乘法分配率的应用,似乎还有一篇,算是入门题. 对了,这题连接:P2220 [HAOI2012]容易题 然而蒟蒻还是先自闭了一会... ...
- C++ 定位错误行
] = {}; SYSTEMTIME st; GetLocalTime(&st); sprintf_s(buf, , "%02d-%02d-%02d %02d:%02d:%02d | ...
- Linux命令:cp命令
cp命令作用:拷贝文件和目录 一.格式 cp [OPTION]... [-T] SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION].. ...
- springcloud-alibaba手写负载均衡的坑,采用restTemplate,不能添加@loadbalanced注解,否则采用了robbin
采用springcloud-alibaba整合rabbion使用DiscoveryClient调用restful时遇到的一个问题,报错如下: D:\javaDevlepTool\java1.8\jdk ...