SQL 高级数据过滤
- 如何组合WHERE子句以建立功能更强,更高级的搜索条件。
一、组合WHERE子句:
- 为了进行更强的过滤控制,
SQL允许给出多个WHERE子句。
这些子句有两种使用方式,以AND子句或者OR子句方式使用。
- 操作符:
用来联结或改变WHERE子句中的子句关键字,也称为逻辑操作符。
1.1:AND操作符:
要通过
不止一个列
进行过滤,可以使用AND操作符
给WHERE子句附加条件:SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id='DLL01' AND prod_price <= 4;
这条SELECT语句中的WHERE子句包含了两个条件,用AND关键字联结再一起。
- AND指示DBMS只返回满足所有给定条件的行。
可以增加多个过滤条件,每个条件间都要使用
AND关键字
注意:
如果加上ORDER BY子句,它应该放在WHERE子句之后。
举个栗子,可以看到ORDER BY 应该放在WHERE之后:
SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id='DLL01' AND prod_price <= 4 ORDER BY prod_name DESC;
1.2:OR操作符:
OR操作符与AND操作符正好相反,它指示DBMS检索匹配任一条件的行。
- 也就是说,再第一个条件满足时,不管第二个条件是否满足,相应的行都被检索出来。
SELECT vend_id, prod_name, prod_price FROM products WHERE vend_id='DLL01' OR vend_id='BRS01';
OR操作符告诉DBMS匹配任一条件而不是同时匹配两个条件
,如果这里使用AND操作符
,则没有数据返回。
1.3:求值顺序:
WHERE子句可以包含任意数目的AND和OR操作符
,但是组合AND和OR会带来一些有趣的问题。举个栗子:
假如需要列出价格为10美元及以上,且由DLL01或BRS01制造的所有产品。
SELECT prod_name, prod_price FROM products WHERE vend_id= 'DLL01' OR vend_id='BRS01' AND prod_price >= 10;
输出结果:
+---------------------+------------+ | prod_name | prod_price | +---------------------+------------+ | Fish bean bag toy | 3.49 | | Bird bean bag toy | 3.49 | | Rabbit bean bag toy | 3.49 | | 18 inch teddy bear | 11.99 | | Raggedy Ann | 4.99 | +---------------------+------------+
可以看出返回了 4条prod_price 价格小于 10美元的信息。为什么会这样呢?
原因在于求值的顺序。
SQL再处理OR操作符前,优先处理AND操作符
。也就是说AND再求值过程中优先级更高,操作符被错误地组合了。此问题的解决方法是
:使用圆括号对操作符进行明确分组。
SELECT prod_name, prod_price FROM products WHERE (vend_id='DLL01' OR vend_id='BRS01') AND prod_price >= 10;
输出结果如下,这是我们想要的结果:
+--------------------+------------+ | prod_name | prod_price | +--------------------+------------+ | 18 inch teddy bear | 11.99 | +--------------------+------------+
因为圆括号具有比AND或OR操作符更高的求值顺序,所以DBMS首先过滤圆括号内的OR条件。
注意:再WHERE子句中使用
圆括号
任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确地分组操作符
。这样更容易理解。
二、IN操作符:
IN操作符用来指定条件范围,范围中每个条件都可以进行匹配
。IN取一组由
逗号分隔、括再圆括号中的合法值
。SELECT prod_name, prod_price FROM products WHERE vend_id IN ('DLL01', 'BRS01') ORDER BY prod_price DESC;
IN操作符后跟由
逗号分隔的合法值
,这些值必须括再圆括号中。其实IN操作符完成了与OR相同的功能
使用IN操作符的
优点
:1.再有很多合法选项时,IN操作符的语法更清楚、更直观。
SELECT prod_name, prod_price FROM products WHERE vend_id IN ('DLL01', 'BRS01');
2.再与其他AND和OR操作符组合使用IN时,求值顺序更容易管理。
SELECT prod_name, prod_id FROM products WHERE vend_id IN ('DLL01', 'BRS01') AND prod_price >= 10;
3.IN操作符一般比一组OR操作符执行的
更快
,再数据很多的情况下,可以清楚的看出检索的速度。4.
IN最大优点是可以包含其他SELECT语句,能够更动态地建立WHERE子句。
三、NOT操作符:
WHERE子句中的NOT操作符有且只有一个功能,那就是否定其后所跟的任何条件。
因为NOT从不单独使用(它总是与其他操作符一起使用),所以它的语法与其他操作符所有不同
。NOT关键字可以用再过滤的列前,而不仅是再其后。
SELECT vend_id, prod_name FROM products WHERE NOT[再过滤的列前使用] vend_id='DLL01' ORDER BY prod_name;
输出结果如下:
+---------+--------------------+ | vend_id | prod_name | +---------+--------------------+ | BRS01 | 12 inch teddy bear | | BRS01 | 18 inch teddy bear | | BRS01 | 8 inch teddy bear | | FNG01 | King doll | | FNG01 | Queen doll | +---------+--------------------+
这里的NOT否定跟在其后的条件,
因此DBMS不是匹配vend_id为'DLL01',而是匹配非'DLL01'之外的所有东西
。上面的NOT关键字也可以使用
<> 或 !=
操作符实现:使用
<>操作符
:SELECT vend_id, prod_name FROM products WHERE vend_id <> 'DLL01' ORDER BY prod_name;
使用
!=操作符
:SELECT vend_id, prod_name FROM products WHERE vend_id != 'DLL01' ORDER BY prod_name;
对于简单的WHERE子句,使用NOT确实没有什么优势。但在更复杂的子句中,NOT非常有用。