本文章为系列文章,是学习《SLQ必知必会》(Ben Forta 著 人民邮电出版社出版)一书的笔记,因此文中大量引用了原书内容, 所以推荐想系统学习的同学阅读原书。同时本文所涉及的相关知识及内容版权由《SLQ必知必会》(Ben Forta 著 人民邮电出版社出版)作者所有,如涉及作品内容、版权或其他问题,将在第一时间删除。本文旨在研究学习使用,禁止用做商业用途。如有其他媒体、网站或个人从本网下载、连接或以其他形式的复制发表、使用所产生的版权等法律问题本站(本人)均不承担责任。
博客地址:http://blog.csdn.net/xiaoyuan511
三、排序检索数据
通过了之前学习的SELECT简单用法,现在来记录一下如何使用SELECT语句的ORDER BY子句,也就是根据需要排序检索出的语句。
在使用ORDER BY子句之前,我们先来看一下什么是子句。
子句
:SQL语句由子句构成,有些句子是必须的,有些是可选的。一个子句通常是由一个关键字加上所提供的数据组成。例如:FROM子句。
为了明确的排序通过SELECT语句检索出的数据,可以使用ORDER BY
子句。例如:
SELECT prod_name FROM Products ORDER BY prod_name;
这个会以字母顺序排序。(注意:在指定一条ORDER BY
子句时,应该保证它是SELECT 语句中最后一条子句
。如果它不是最后的子句,将会出现错误消息。)
同时,在很多时候需要按不止一个列进行数据排序,比如说员工名单,如果多个员工具有相同的姓时,那么在每个姓中按名排序。要按多个列排序,简单指定列名,列名之间用逗号分隔。下面这段代码是检索三个列,并按照其中两个列对结果进行排序——首先按价格,然后按名称。
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price, prod_name;
上面这段代码的作用是会按照price进行排序,只有当price相同时才会在按照name进行排序。同时也可以按列位置排序,例如:
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY 2, 3;
意思同上,先按照SELECT清单中第二个列prod_price排序,再按第三个列prod_name排序。
同样,众所周知在排序上并不是只有升序排序
(这个只是默认的排序顺序),有时候还要通过ORDER BY进行降序排序
,这个时候必须制定DESC
关键字。例如:
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC;
这就表示了按价格降序排列。那么如果打算用多个列排序该怎么办呢:
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC, prod_name;
这样就可以先按pice降序,而prod_name则仍然按照默认的升序排列。由此可知,DES关键字只应用到直接位于其前面的列名,所以如果想在多个列上进行降序排序,必须对每一列指定DESC关键字。
四、过滤数据
通过3中排序检索学习之后,来学习一下如何过滤数据,也就是如何使用SELECT语句
的WHERE子句指定搜索条件。在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。WHERE子句在表名(FROM子句)之后给出,例如:
SELECT prod_name, prod_price FROM Products WHERE prod_price = 3.49;
这条语句代表的意思就是他会检索prod_name和prod_price两个列,但是并不会全部返回,只会返回prod_price的值为3.49的值。(如果同时使用ODER BY
和 WHERE
子句时,要保证ORDER BY 在 WHERE 之后。)
在上个例子中,我们看到了相等的操作符,那么他是否支持其他的操作符呢?
操作符 | 说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
!< | 不小于 |
> | 大于 |
>= |
大于等于 |
!> | 不大于 |
BETWEEN…AND | 在指定的两个值之间 |
IS NULL | 为NULL值 |
在相等的例子之后,我们来看一下其他条件的例子:
1.小于
SELECT prod_name, prod_price FROM Products WHERE prod_price < 10;
2.小于等于
SELECT prod_name, prod_price FROM Products WHERE prod_price <= 10;
3.不匹配检查(例如:不是DLL01制造的的产品)
SELECT vend_id, prod_name FROM Products WHERE vend_id <> ‘DLL01’;(<> 和 !=可以互换,意义相同)
4.范围检查(输出price值在5~10之间)
SELECT prod_name, prod_price FROM Products WHERE prod_price BETWEEN 5 AND 10;
5.空值检查(它与字段包含0、空字符串或仅仅包含空格不同,确定值是否为空不能简单地检查是否 = NULL,而要用这个 IS NULL子句)
SELECT prod_name FROM Products WHERE prod_price IS NULL;
事例这个就是建厂返回没有价格(空prod_price字段,不是价格为0)的产品。
五、高级数据过滤
WHERE的用法并不仅是上面的简单,他还有很多高级用法,下面我们学习组合WHERE子句。在SQL中,为了进行更强的过滤控制,允许给出多个WHERE子句。这些句子有两种使用方式,即以AND子句或OR子句的方式使用。
操作符
:用来联结或改变WHERE子句中的子句的关键字,也称为逻辑操作符。
AND操作符
:要通过不止一个列进行过滤,可以使用AND操作符给WHERE子句附加条件,例如:
SELECT prod_id, prod_price, prod_nam FROM Products WHERE vend_id = ‘DLL01’ AND prod_price <= 4;
这句话的意思就是检索出制造商为DLL01且价格小于等于4的商品。同理,可以使用多个过滤条件,每个条件之间都要使用ADN关键字。
OR
操作符:OR
操作符与AND
操作符正好相反,它是匹配任一条件的行。比如第一个条件满足了,那么他就不会检索第二个条件,而是会直接输出,同理,如果第一个条件没有满足,但是第二个或者之后的条件满足了,那么他同样会输出。例如:
SELECT prod_name, prod_price FROM Products WHERE vend_id = ‘DLL01’ OR vend_id = ‘BRS01’;
他会输出制造商为DLL01或者BRS01的产品。
ADN:用在WHERE子句中的关键字,用来指示检索满足所有给定条件的行。
OR:用在WHERE子句中的关键字,用来表示检索匹配任一给定条件的行。
过了解上面和AND或OR之后,我们知道WHERE子句可以包含任意数目的AND和OR。那么,问题来了,同时使用AND和OR的时候,有优先级之分么?还是他们两个是平级的顺序?
答案是:AND在求值过程中优先级更高。因此如下段代码:
SELECT prod_name, prod_price FROM Products WHERE vend_id = ‘DLL01’ OR vend_id = ‘BRS01’ AND prod_price >= 10;
这段代码的实际意义是,由供应商BRS01制造的prod_price>=10的产品,或制造商为DELL01的全部产品。那么如果我们想要制造商为DLL01或者BRS01,他们大于10的产品应该怎么写呢?
SELECT prod_name, prod_price FROM Products WHERE (vend_id = ‘DLL01’ OR vend_id = ‘BRS01’) AND prod_price >= 10;
答:如同运算法则一样,加个括号即可。
(小提示:任何时候在使用具有AND和OR操作符的WHERE 子句,都应该使用括号明确的分组操作符,这样的话它会尽最大可能消除歧义同时便于理解。)
写到这里,又有了疑问了,那就是如果我需要制造商为N家的产品时,那么我是否需要: xxx OR xxx OR xxx OR xxx…,难道没有更加简洁优雅的方法么?
答案是,有的,可以用IN操作符。
举个例子:
SELECT prod_name, prod_price FROM Products WHERE vend_id IN (‘DLL01’, ‘BRS01’)
这块引用书中的原话就是:
- 在有很多合法选项时,IN操作符的语法更清楚,更直观。
- 在与其他AND和OR操作符组合使用IN时,求值顺序更容易管理。
- IN操作符一般比一组OR操作符执行更快。
- IN的最大优点是可以包含其他SELECT语句,能够更动态的简历WHERE子句。
现在,让我们来看一下本章要学的最后一个操作符——NOT操作符。
NOT
:WHERE 子句中用来否定其后条件的关键字。
NOT关键字在WHERE子句中有且只有一个功能,就是否定其后所跟的任何条件。因为NOT从来不单独使用,所以他的语法与其他操作符有所不同。NOT关键字可以用在要过滤的列前而不仅是在其后。例如:
SELECT prod_name FROM Products WHERE NOT vend_id = ‘DLLO1’ ORDER BY prod_name;
这个例子的意思就是匹配非DLL01之外所有的东西。(是的,跟之前的!= 或者 <> 一个效果)
六、用通配符进行过滤
在经过之前的学习之后,现在来看一下什么是通配符、如何使用通配符以及怎样使用LIKE操作符进行统配搜索。在之前学习的所有操作符都是针对已知值进行过滤的。但是这种过滤方法不是在任何时候都好用,例如:如何搜索产品名中包含 bean bag的所有产品?这就可以通过使用通配符来实现。
通配符
:用来匹配值的一部分的特殊字符。
搜索模式
:由字面值、通配符或两者组合构成的搜索条件。
通配符实际上是SQL的WHERE子句中有特殊含义的字符。在搜索子句中使用通配符,必须使用LIKE操作符。(LIKE其实是谓词不是操作符。。。)
通配符搜索只能用于文本字段(字符串),非文本数据类型字段不能使用通配符搜索。
百分号(%)通配符
最常使用的通配符是百分号(%)。在搜索串中,%表示任何字符出现任意次数。例如:
SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE ‘Fish%’;
以上语句的意思是找出所有已Fish起头的产品。(根据DBMS配置不同,可以区分大小写。)
通配符可以在搜索模式中的任意位置使用,并且可以使用多个通配符。如下面的例子:
SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE ‘%bean bag%’;
表示匹配任何位置上包含文本bean bag的值,不论它之前或之后出现什么字符。他也可以在中间使用:
SELECT prod_name FROM Products WHERE prod_name LIKE ‘F%y’;
它代表搜索以F开头y结尾的搜索结果(可以用在查找一份邮件之类的)。要注意的是,通配符%看起来可以匹配任何东西,但是无法匹配NULL。也就是说 WHERE prod_name LIKE ‘%’ 不会匹配产品名称为NULL的行。
下划线(_)通配符
:用途与%一样,只是匹配单个字:
SELECT prod_name FROM Products WHERE prod_name LIKE ‘__ inch teddy bear’;
他会查找在 inch teddy bear之前恰好有两个字符所匹配的项。
书中总结了使用通配符的技巧,如下:
- 不要过度是用通配符。如果其他操作符能达到相同的目的,应该使用其他的操作符。
- 在确实需要使用通配符时,也尽量不要把他们用在搜索模式的开始处。把通配符至于开始处,搜索起来是最慢的。
- 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。