MySQL:SELECT 语句
禁止码迷,布布扣,豌豆代理,码农教程,爱码网等第三方爬虫网站爬取!
SELECT
看看现在几点了?
select Now();
检索语句
SELECT 语句顾名思义就是有检索功能啦,通过这个语句就可以从不小于 1 个表中提取信息了。当你使用该语句是,你需要给出检索什么信息、从什么地方检索。
- SQL 语句不区分大小写,因此 “SELECT” 和 “select” 语句都是有效的。
- SQL 语句的所有空格会被忽略,因此语句也可以分成好几行来写,这样可读性也比较好。
检索列
单个列
检索列时,需要给出列的名称和检索的表名。
多个列
检索多个列时,需要给出多个列的名称和检索的表名,多个列的名称用 “,” 隔开。
- 多余的 “,” 将会引发错误。
- SQL 返回的是无格式的数据,因此当我们要在程序中用这些数据往往需要格式化。
所有列
检索多个列时,需要给出检索的表名,用 “*” 通配符来实现这个功能。
- 除非你确实需要所有列,否则别用,因为检索都是有开销的。
检索不同行
检索时我们可能会检索到很多重复的数据,若我们只想要类似 set 容器那样只有不重复的数据,那就需要用 DISTINCT 关键字来限制仅返回不同的值。
- DISTINCT 关键字应用于所有列,所有不同行都会被检索出来。
限制检索数
有时候我不想看全部的检索结果,而是看看其中的某几行,可以用 LIMIT 语句,表示不多于的限制条件。
LIMIT 语句的参数可以是 2 个,表示要开始检索的行和展示的行数:
- LIMIT 语句的检索从第 0 号开始计算。
当行数不够 LIMIT 的限制时,就返回仅有的行:
当然如果你在 MySQL 5 中,这么写也可以:
LIMIT num1 OFFSET num2
表示从行 num2 开始取 num1 行。
完全限定
检索结果排序
OEDER BY 子句
使用 OEDER BY 子句可以对检索的结构排序:
按列排序
排序的时候我们可能不是按照某一列来排序,可能多个列都要考虑,这个时候就可以用 “,” 隔开。
降序排序
指定 DESC 关键字之后就可以进行降序排序。
对多个列来说也可以给某一个列加关键字:
与之相对应的是 ASC 关键字,不过因为升序序列是默认的,因此这个关键字几乎不用。
数据过滤
WHERE 字句
当我的数据量比较大的时候,我们检索时可能只需要其中的某几个数据,那就需要去过滤检索的结果。使用 WHERE 子句可以指定检索的条件。语法框架为:
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
- 我们也可以在编写程序的时候写对应的检索算法,但是这样可能时间、空间复杂度就会很大。因此对于服务器,数据库若本身就能进行过滤的话科技节省开销。
- ORDER BY 子句必须要放在 WHERE 子句之后用。
检索多个值
就是把 “=” 替换为 “>”、“<”、 “>=”、“<=” 和系列操作符:
不匹配检查
通过 “!=” 操作符或 “<>” 操作符实现,两者效果相同。
范围检查
使用操作符 “BETWEEN”,该操作符需要提供 2 个值,也就是范围的开始值和结束值。
NULL 检查
数据库的列中是可以没有值的,这个时候值就为 NULL。要检索这样的值需要用 “IS NULL” 子句。
- 我们可能希望检索到不具有特定值的行,但是由于其没有特殊含义,因此数据库不会返回。因此一定要验证数据是否有 NULL。
逻辑操作符
AND
可以用 AND 操作符附加多个过滤条件:
OR
OR 操作符可以表示匹配任意条件:
当然以上 2 个操作符可以混用:
IN
当我们要检索的数据在一个给定的数据集时,可以用 IN 操作符,在操作符后面要有一个用圆括号括起来的数据集合:
使用 IN 操作符有以下优点:
- 拥有已知的检索基准时,IN 操作符使语法更为简洁;
- IN 操作符的操作次序的计算更为明确;
- IN 操作符的执行效率比多个 OR 操作符更快;
- IN 操作符可以内嵌其他 DELECT 语句。
NOT
NOT 操作符可以否定它之后的条件:
通配符过滤
前面的检索都是已知检索值的,但是检索值并不往往是已知的,那就是需要结合通配符做模糊查找。所谓通配符就是匹配一部分的特殊字符。当我们使用通配符时,需要结合 WHERE 子句和 LIKE 操作符,这可以表示后面的操作模式是用通配符匹配。所谓操作模式可以理解为一种搜索条件的类型。
%
% 表示任意字符出现过任意次数。例如下面实例可以判断所有以 “Dum” 起头的词,% 表示不在乎后面有多少个字符:
这个搜索是区分大小写的,用多个通配符可以检索任意位置:
通配符也可以放中间:
- % 可以检索 0 字符,但是不能匹配 NULL。
- 检索时需要注意空格的干扰,这个也会被匹配进去。这个时候可以在搜索模式后面加一个 % 来解决问题。
_
_ 和 % 的作用一样,但是 _ 只能匹配单个字符:
为什么?因为该通配符值只关心所在的一个字符,有多个字符它不管,这与 % 区别有点大:
使用技巧
使用通配符虽然方便,但是开销比较大,因此使用起来需要一些技巧:
- 若用其他操作符可以实现,不要使用通配符;
- 使用通配符是要避免在搜索模式的开始处;
- 通配符需要找对位置使用,否则可能检索到我们不想看到的数据。
数据分组
有时候我们倾向于把检索的的数据按照一定的特点进行分组,通过分组后将有助于进行数据分析。
创建分组
分组使用 CROUP BU 子句建立,该子句可以根据我们给定的规则将检索结果分为不同的组。CROUP BU 子句有比较多的使用规则:
- 该子句可以包含任意数目的列;
- 子句中列出的每个列都必须是检索的列,或者是有效的表达式,但是不能是聚集函数;
- 聚集语句以外的字段都必须在子句中给出;
- 分组中值为 NULL 的元素将被分在同一组;
- 建立分组时,所有包含的列一并进行计算,即使存在分组也不能够从中提取数据。
例如下面的代码就可以把行按照相同的值分为几组:
再对照一下数据库本身的数据:
在上述例子中,我们可以看到数据根据我们指定的字典被分了组,并且统计了每组的数据元素个数。
分组过滤
我们在前面熟悉了用 WHERE 子句对行进行过滤,但是不能用来过滤分组。想要过滤分组,就需要使用 HAVING 子句来完成,同时这个子句也可以胜任 WHERE 能完成的所有工作,他们的用法是相通的。
那么怎么理解两种非常类似的语句呢?除了操作对象的不同,它们也有着次序的不同,WHERE 子句在 SELECT 中的位置先于 HAVING 子句,也就是对于一次检索的过滤顺序为先对行过滤,再对分组过滤。这是因为我们可能只是想提取检索到的数据中的部分数据,然后根据这些数据再来创建分组。
当然我们也可以观察出一个显然的事情,GROUP 子句的顺序也在 HAVING 子句前面,因为我得先有分组才能操作之。
分组排序
好像 CROUP BU 子句本身在在分组的同时也会进行排序,但是我们还是需要 ORDER BY 子句的联合使用。CROUP BU 子句是对分组进行排序,不过这并不是规范所要求的功能:
而 ORDER BY 可以针对某一字段来排序:
SELECT 语法框架
SELECT column_name,column_name…
FROM table_name
[WHERE]
[GROUP BY]
[HAVING]
[ORDER BY]
[LIMIT]
参考资料
《MySQL Crash Course》[英] Ben Forta 著,刘晓霞 钟鸣 译,人民邮电出版社
菜鸟教程——MySQL 教程