MySQL 检索记录 Select 语句详解
数据库最普遍的操作就是“插、查、删,改”。在前在的日志中,我为大家介绍过MySQL的 insert 插入语句,也为大家介绍过 update 更新语句,以及删除语句 delete 和 truncate语句。今天就为大家来介绍一下,MySQL中唯一的检索数据语句:select语句。
select 语句是SQL开发者最常用的语句,也是最强大的武器,幸运在的是,学习这个语句并不是很难。
select 语句的定义:
一切都要遵循规矩来办事,所以和之前的教程一样,我们先来看一下手册上面说的 select 语句的语法结构:
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr, ...
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name']
[FROM table_references
[WHERE where_definition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_definition]
[ORDER BY {col_name | expr | position}
[ASC | DESC] , ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[FOR UPDATE | LOCK IN SHARE MODE]]
呵呵,看到了吧?其语法是相当的长了,但是有一点大家要知道,中括号内部的是可以省略的。有的时候是用不到这些东西的。我们一点点来,不要被这语法吓到,其实 select 语句还是很简单的,之所以语法这么复杂, 那是因为 select 语句是非常强大的。
select 执行数学运算:
我们可以使用select语句来执行数学运算,当然,如果公式太复杂的话就算了,否则数学学家不就死绝了?哈哈。 简单给大家几个例子,说明一下问题就行,至于一百以内的加减法咱就自己算了,就不麻烦 MySQL 了哈。呵呵。
/*
+-----------+-----------+---------+
| 100 + 100 | 50>=(2+3) | 100/3 |
+-----------+-----------+---------+
| 200 | 1 | 33.3333 |
+-----------+-----------+---------+
1 row in set (0.00 sec)
*/
select 检索指定的行和列:
select 语句支持 * 通配符,表示获得所有的字段。同时,也支持用户自己指定字段名,来返回指定的列。例如,如下语句返回的是之前用过的 twitter 插件的所有数据列,就可以使用 * 这个通配符。
/*
*************************** 1. row ***************************
id: 16628009
name: simaopig
screen_name: simaopig
location:
description:
profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/180700745/head_normal.png
url: http://www.xiaoxiaozi.com
protected: 1
followers_count: 1
1 row in set (0.00 sec)
*/
如果我只想看其中的 url 和 name 字段的所有信息就可以使用如下语句,将返回的结果集指定所要展示的列的字段名:
/*
+----------+---------------------------+
| name | url |
+----------+---------------------------+
| simaopig | http://www.xiaoxiaozi.com |
+----------+---------------------------+
1 row in set (0.00 sec)
*/
select 为查询结果加上限制条件:
我们可以使用where子句来为select语句指定所要查询的限制条件,只要满足where子句的结果才会展示在结果集中,例如下面语句,我希望从wp_threadtwitter_users 中只返回name为simaopig的用户的url,就可以使用如下语句:
/*
+---------------------------+
| url |
+---------------------------+
| http://www.xiaoxiaozi.com |
+---------------------------+
1 row in set (0.00 sec)
*/
where子句也可以指定更复杂的范围,比如说,我想查询一下,我发表的日志中,评论数大于30,并且小于50的文章id及title就可以指定如下子句:
/*
+-----+-------------------------------------------------------+---------------+
| id | post_title | comment_count |
+-----+-------------------------------------------------------+---------------+
| 488 | 海运女,又一个倒霉蛋 | 46 |
| 501 | 解决Mail to Commenter发出的邮件被当作垃圾 | 36 |
+-----+-------------------------------------------------------+---------------+
2 rows in set (0.01 sec)
*/
select 使用内建函数:
long long ago,我为大家介绍过MySQL的函数部分,MySQL为大家提供了非常丰富的内建函数来满足大家日常的需要,下面我为大家举两个例子,分别使用 MAX , MIN, COUNT 这三个函数,来返回我发表日志的评论最多的文章,和评论最少的文章,以及我发表日志的总数:
/*
+--------------------+--------------------+
| max(comment_count) | min(comment_count) |
+--------------------+--------------------+
| 362 | 0 |
+--------------------+--------------------+
1 row in set (0.01 sec)
*/
由上面结果可以看出,我还有文章的沙发保存至今呢。呵呵,哪位有兴趣可以去翻一下,抢一下这落了好多灰的沙发。呵。
/*
+----------+
| count(*) |
+----------+
| 340 |
+----------+
1 row in set (0.00 sec)
*/
由结果可以看出,算上我保存的草稿,本站从建立至今,小小子已经写过340篇日志了,虽然其中草稿占了很大一个比重。呵呵。不过,总是自己一个字一个字敲的。哈。
select 为表取别名:
有的时候,我们要查询的表的名字太长了,经常敲这些名字是很累人的,尤其是我这种懒人,MySQL为我们提供了表的别名机制,使我们在查询的时候可以给表起个别名,大家可以理解为起外号,比如我管“小猫”叫“犊子”,那么当我喊“犊子”的时候,某人当然知道我是在叫他。哈。
为表起别名,可以在用select 语句指定查询的表名后面用 as 子句来指定,例如下面我为wp_threadtwitter_users 起别名为 users,并且在后面的查询中,我用别名指定字段,这在子查询中是很方便的,呵
/*
*************************** 1. row ***************************
id: 15367683
name: Wu
screen_name: mg12
location: Guangzhou, China
description:
profile_image_url: http://s3.amazonaws.com/twitter_production/profile_images/56577657/96x96_normal.png
url: http://www.neoease.com/
protected: 0
followers_count: 217
1 row in set (0.00 sec)
*/
select 限制查询结果的个数:
有的时候查询到的结果数目太多了,以至于一个屏幕都显示不下,那我们咋看这结果了?别急,MySQL为我们提供了limit子句,其和select语句一起使用时,可以限制查询结果的个数,limit子句后面直接跟想要取得的结果集的行数,使用方法如下:
/*
+-----+
| id |
+-----+
| 86 |
| 488 |
+-----+
*/
也可以指定一个偏移量,例如,下面的例子从第4行(注意,是从0开始计数的)开始,返回2条记录:
/*
+----+
| id |
+----+
| 26 |
| 28 |
+----+
2 rows in set (0.00 sec)
*/
select 对查询结果进行分组和排序:
MySQL提供了order by 和 group by ,结合select 语句,我们可以对查询返回的结果进行排序和分组。可以在order by子句向两个字段添加asc 和 desc关键字来定制排序方法,如果没有指定order by 子句,MySQL对结果集的排序默认为升序。相应字段的值以升序或者降序的顺序被排序。而group by 后面直接跟字段名,意思为按该字段为查询结果分组:
取小小子发表的博客日志的文章id,取3条,按照id来倒序排列:
/*
+------+
| id |
+------+
| 1451 |
| 1450 |
| 1449 |
+------+
3 rows in set (0.00 sec)
*/
比如下面的例子,我把wordpress的友情链接,按照link_rel分组,来取其中的前两条记录,可以使用如下语句:
/*
*************************** 1. row ***************************
link_rel:
link_name: LAONB
*************************** 2. row ***************************
link_rel: acquaintance
link_name: 衡天小张主机
2 rows in set (0.02 sec)
*/
select 使用变量和子查询:
这节是滥竽充数的,因为本篇日志不对其进行解释,在后面的日志中,小小子会专门写一篇关于MySQL子查询的日志来为大家讲解。至于使用变量嘛,一般用不到,咱就不瞎白话了,免得误人子弟就罪过了。
控制 select 的行为:
可以向select 语句添加很多关键字来修改行为:
- DISTINCT关键字删除包含结果信中具有重复值的记录
- SQL_CALC_FOUND_ROWS关键字告诉MySQL计算符合查询(不需要考虑可能设置的任何LIMIT)的总行数。通过调用FOUND_ROWS()函数可以得到总行数
- SQL_CACHE 和SQL_NO_CACHE关键字告诉MySQL查询结果是否需要高速缓存
- SQL_BUFFER_RESULT关键字强制MySQL把查询结果存储到一个临时表。这使缓冲器消除了对查询所使用的表的锁定,而且结果被传送给客户,因而可以暂被其他进程使用
- SQL_BIG_RESULT 和SQL_SMALL_RESULT关键字可以指定结果集的期望大小,因此可帮助找到最佳的方法对返回的记录进行排序和存储(基于磁盘或者内存中的临时表)
- SQL_HIGH_PRIORITY关键字提升了与UPDATE,INSERT和DELETE语句相竞争的查询的优先级,因而可以在繁忙的数据库服务器上快速的执行查询
总结及唠叨:
好久没写过这么长的日志了,最近变的很懒。这些东西也是早就看过了,不过一直没有时间写,或者是一直懒的写,因为各位也看到了,这篇真的好长。呵呵,写了一个多小时,而且程序要一点点的敲,不能给大家错误的展示不是?呵呵。
本文除了最后“控制 select 的行为“的部分,小小子都是经常使用的,希望可以帮到有需要的人,如果列位不需要,捧个人场吧,哈。
文章作者:simaopig
本文地址:http://www.xiaoxiaozi.com/2009/09/12/1451/
版权所有 © 转载时必须以链接形式注明作者和原始出处!
你脑子真好使,可以记住那么多东西!佩服!
[回复]
@JiaCheng
呵呵。。我都是一边看书。一边敲程序,然后一边写日志的。要不然让我临时写我也写不出来啊。呵。
[回复]
哈哈,我到学校啦,来你博客踩一脚。
[回复]
@荒野无灯
哈哈,你终于开学了。哈。
PS:我还用你原来的域名呢,用换不?我看你是301,应该没啥影响吧,而且你原来域名也有效。呵。
[回复]
原来是换IP了,我说最近RSS怎么没更新= =
[回复]
@hslx111
RSS 更新是很慢的。呵呵。
[回复]
给你一脚,让你记得我来了!
[回复]
写得真抽象,俺看书去
[回复]
怎么这么久了才写select语句…这语句已经用了XXX遍了,不过exists语句我就是他奶奶的用不好,exists相当重要阿….
[回复]
你很精通MySQL啊?呵呵!
[回复]
@阿飞
正是因为不会才写的。。呼。呵呵。工作中学习。
[回复]
@simaopig
MySQL在企业中占有度有多大啊?感觉大部分企业用的都是Oracle……
[回复]
@阿飞
呵呵,JAVA一般是用的ORACLE,而PHP一般都用MySQL的。所以其占有度,很高。 :cool:
[回复]
@simaopig
;-) :smile:
[回复]