SQL 入门 -- 数据过滤(二)
数据过滤
通过条件约束筛选出符合条件的结果,减少不必要的数据行。
数据过滤重点内容
1、使用 WHERE 子句,如何使用比较运算符对字段的数值进行比较筛选;
2、如何使用逻辑运算符,进行多条件的过滤;
3、学会使用通配符对数据条件进行复杂过滤。
比较运算符
在 SQL 中,我们可以使用 WHERE 子句对条件进行筛选,在此之前,你需要了解 WHERE 子句中的比较运算符。这些比较运算符的含义你可以参见下面这张表格:
实际上你能看到,同样的含义可能会有多种表达方式,比如小于等于,可以是(<=),也可以是不大于(!>)。同样不等于,可以用(<>),也可以用(!=),它们的含义都是相同的,但这些符号的顺序都不能颠倒,比如你不能写(=<)。需要注意的是,你需要查看使用的 DBMS 是否支持,不同的 DBMS 支持的运算符可能是不同的,比如 Access 不支持(!=),不等于应该使用(<>)。在 MySQL 中,不支持(!>)(!<)等。
WHERE 子句的基本格式是:
SELECT ……(列名) FROM ……(表名) WHERE ……(子句条件)
比如我们想要查询所有最大生命值大于 6000 的英雄:
SQL:SELECT name, hp_max FROM heros WHERE hp_max > 6000
想要查询所有最大生命值在 5399 到 6811 之间的英雄:
SQL:SELECT name, hp_max FROM heros WHERE hp_max BETWEEN 5399 AND 6811
我们也可以对 heros 表中的hp_max字段进行空值检查。
SQL:SELECT name, hp_max FROM heros WHERE hp_max IS NULL
逻辑运算符
刚才介绍了比较运算符,如果我们存在多个 WHERE 条件子句,可以使用逻辑运算符:
假设想要筛选最大生命值大于 6000,最大法力大于 1700 的英雄,然后按照最大生命值和最大法力值之和从高到低进行排序。
SQL:SELECT name, hp_max, mp_max FROM heros WHERE hp_max > 6000 AND mp_max > 1700 ORDER BY (hp_max+mp_max) DESC
如果 AND 和 OR 同时存在 WHERE 子句中会是怎样的呢?假设我们想要查询最大生命值加最大法力值大于 8000 的英雄,或者最大生命值大于 6000 并且最大法力值大于 1700 的英雄。
SQL:SELECT name, hp_max, mp_max FROM heros WHERE (hp_max+mp_max) > 8000 OR hp_max > 6000 AND mp_max > 1700 ORDER BY (hp_max+mp_max) DESC
你需要注意到,当 WHERE 子句中同时存在 OR 和 AND 的时候,AND 执行的优先级会更高,也就是说 SQL 会优先处理 AND 操作符,然后再处理 OR 操作符。
如果我们对这条查询语句 OR 两边的条件增加一个括号呢?
SQL:SELECT name, hp_max, mp_max FROM heros WHERE ((hp_max+mp_max) > 8000 OR hp_max > 6000) AND mp_max > 1700 ORDER BY (hp_max+mp_max) DESC
当 WHERE 子句中同时出现 AND 和 OR 操作符的时候,你需要考虑到执行的先后顺序,也就是两个操作符执行的优先级。一般来说 () 优先级最高,其次优先级是 AND,然后是 OR。
如果我想要查询主要定位或者次要定位是法师或是射手的英雄,同时英雄的上线时间不在 2016-01-01 到 2017-01-01 之间。
SQL: SELECT name, role_main, role_assist, hp_max, mp_max, birthdate FROM heros WHERE (role_main IN ('法师', '射手') OR role_assist IN ('法师', '射手')) AND DATE(birthdate) NOT BETWEEN '2016-01-01' AND '2017-01-01' ORDER BY (hp_max + mp_max) DESC
你能看到 WHERE 子句被分成了两个部分。第一部分是关于主要定位和次要定位的条件过滤,使用的是role_main in ('法师', '射手') OR role_assist in ('法师', '射手')。这里用到了 IN 逻辑运算符,同时role_main和role_assist是 OR(或)的关系。
第二部分是关于上线时间的条件过滤。NOT 代表否,因为要找到不在 2016-01-01 到 2017-01-01 之间的日期,因此用到了NOT BETWEEN '2016-01-01' AND '2017-01-01'。同时是在对日期类型数据进行检索,所以使用到了 DATE 函数,将字段 birthdate 转化为日期类型再进行比较。
使用通配符进行过滤
刚才的条件过滤都是对已知值进行的过滤,还有一种情况是要检索文本中包含某个词的所有数据,这里就需要使用通配符。通配符就是用来匹配值的一部分的特殊字符。这里我们需要使用到 LIKE 操作符。
如果想要匹配任意字符串出现的任意次数,需要使用(%)通配符。比如想要查找英雄名中包含“太”字的英雄都有哪些:
SQL:SELECT name FROM heros WHERE name LIKE '%太%'
需要说明的是不同 DBMS 对通配符的定义不同,在 Access 中使用的是(*)而不是(%)。另外关于字符串的搜索可能是需要区分大小写的,比如'liu%'就不能匹配上'LIU BEI'。具体是否区分大小写还需要考虑不同的 DBMS 以及它们的配置。
如果我们想要匹配单个字符,就需要使用下划线 () 通配符。(%)和()的区别在于,(%)代表零个或多个字符,而(_)只代表一个字符。
SQL:SELECT name FROM heros WHERE name LIKE '_%太%'
能看出来通配符还是很有用的,尤其是在进行字符串匹配的时候。不过在实际操作过程中,建议你尽量少用通配符,因为它需要消耗更多的数据库资源。即使对 LIKE 检索的字段添加了索引,索引的价值也可能会失效。如果要让索引生效,那么 LIKE 后面就不能以(%)开头,比如使用LIKE '%太%'或LIKE '%太'的时候就会对全表进行扫描。如果使用LIKE '太%',同时检索的字段进行了索引的时候,则不会进行全表扫描。
表字段说明:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App