首页 > MySQL > MySQL 检索记录 Select 语句详解
2009九月12

MySQL 检索记录 Select 语句详解

数据库最普遍的操作就是“插、查、删,改”。在前在的日志中,我为大家介绍过MySQL的 insert 插入语句,也为大家介绍过 update 更新语句,以及删除语句 delete 和 truncate语句。今天就为大家来介绍一下,MySQL中唯一的检索数据语句:select语句。

select 语句是SQL开发者最常用的语句,也是最强大的武器,幸运在的是,学习这个语句并不是很难。

select 语句的定义:

一切都要遵循规矩来办事,所以和之前的教程一样,我们先来看一下手册上面说的 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 了哈。呵呵。

select 100 + 100, 50>=(2+3) , 100/3;
/*
+-----------+-----------+---------+
| 100 + 100 | 50>=(2+3) | 100/3   |
+-----------+-----------+---------+
|       200 |         1 | 33.3333 |
+-----------+-----------+---------+
1 row in set (0.00 sec)
*/

select 检索指定的行和列:

select 语句支持 * 通配符,表示获得所有的字段。同时,也支持用户自己指定字段名,来返回指定的列。例如,如下语句返回的是之前用过的 twitter 插件的所有数据列,就可以使用 * 这个通配符。

select * from wp_threadtwitter_users \G ;
/*
*************************** 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 字段的所有信息就可以使用如下语句,将返回的结果集指定所要展示的列的字段名:

select name,url from wp_threadtwitter_users ;
/*
+----------+---------------------------+
| name     | url                       |
+----------+---------------------------+
| simaopig | http://www.xiaoxiaozi.com |
+----------+---------------------------+
1 row in set (0.00 sec)
*/

select 为查询结果加上限制条件:

我们可以使用where子句来为select语句指定所要查询的限制条件,只要满足where子句的结果才会展示在结果集中,例如下面语句,我希望从wp_threadtwitter_users 中只返回name为simaopig的用户的url,就可以使用如下语句:

 select url from wp_threadtwitter_users where name = 'simaopig';
/*
+---------------------------+
| url                       |
+---------------------------+
| http://www.xiaoxiaozi.com |
+---------------------------+
1 row in set (0.00 sec)
*/

where子句也可以指定更复杂的范围,比如说,我想查询一下,我发表的日志中,评论数大于30,并且小于50的文章id及title就可以指定如下子句:

select id,post_title,comment_count from wp_posts where comment_count > 30 and comment_count < 50 limit 2;
/*
+-----+-------------------------------------------------------+---------------+
| 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 这三个函数,来返回我发表日志的评论最多的文章,和评论最少的文章,以及我发表日志的总数:

select max(comment_count),min(comment_count) from wp_posts;
/*
+--------------------+--------------------+
| max(comment_count) | min(comment_count) |
+--------------------+--------------------+
|                362 |                  0 |
+--------------------+--------------------+
1 row in set (0.01 sec)
*/

由上面结果可以看出,我还有文章的沙发保存至今呢。呵呵,哪位有兴趣可以去翻一下,抢一下这落了好多灰的沙发。呵。

select count(*) from wp_posts;
/*
+----------+
| count(*) |
+----------+
|      340 |
+----------+
1 row in set (0.00 sec)
*/

由结果可以看出,算上我保存的草稿,本站从建立至今,小小子已经写过340篇日志了,虽然其中草稿占了很大一个比重。呵呵。不过,总是自己一个字一个字敲的。哈。

select 为表取别名:

有的时候,我们要查询的表的名字太长了,经常敲这些名字是很累人的,尤其是我这种懒人,MySQL为我们提供了表的别名机制,使我们在查询的时候可以给表起个别名,大家可以理解为起外号,比如我管“小猫”叫“犊子”,那么当我喊“犊子”的时候,某人当然知道我是在叫他。哈。

为表起别名,可以在用select 语句指定查询的表名后面用 as 子句来指定,例如下面我为wp_threadtwitter_users 起别名为 users,并且在后面的查询中,我用别名指定字段,这在子查询中是很方便的,呵

select * from  wp_threadtwitter_users  as users where screen_name like '%mg%' and users.followers_count > 200 \G
/*
*************************** 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子句后面直接跟想要取得的结果集的行数,使用方法如下:

select id from wp_posts where id > 3 and comment_count > 30 limit 2;
/*
+-----+
| id  |
+-----+
|  86 |
| 488 |
+-----+
*/

也可以指定一个偏移量,例如,下面的例子从第4行(注意,是从0开始计数的)开始,返回2条记录:

 select id from wp_posts limit 3,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来倒序排列:

select id from wp_posts  order by id desc limit 3;
/*
+------+
| id   |
+------+
| 1451 |
| 1450 |
| 1449 |
+------+
3 rows in set (0.00 sec)
*/

比如下面的例子,我把wordpress的友情链接,按照link_rel分组,来取其中的前两条记录,可以使用如下语句:

select link_rel,link_name from wp_links as links group by link_rel limit 2 \G
/*
*************************** 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/
版权所有 © 转载时必须以链接形式注明作者和原始出处!

14 Responses to “MySQL 检索记录 Select 语句详解”

  1. #1 JiaCheng 回复 | 引用 Post:2009-09-12 15:43

    你脑子真好使,可以记住那么多东西!佩服!

    [回复]

  2. #2 simaopig 回复 | 引用 Post:2009-09-12 17:14

    @JiaCheng
    呵呵。。我都是一边看书。一边敲程序,然后一边写日志的。要不然让我临时写我也写不出来啊。呵。

    [回复]

  3. #3 荒野无灯 回复 | 引用 Post:2009-09-12 17:51

    哈哈,我到学校啦,来你博客踩一脚。

    [回复]

  4. #4 simaopig 回复 | 引用 Post:2009-09-12 19:21

    @荒野无灯
    哈哈,你终于开学了。哈。

    PS:我还用你原来的域名呢,用换不?我看你是301,应该没啥影响吧,而且你原来域名也有效。呵。

    [回复]

  5. #5 hslx111 回复 | 引用 Post:2009-09-13 16:20

    原来是换IP了,我说最近RSS怎么没更新= =

    [回复]

  6. #6 simaopig 回复 | 引用 Post:2009-09-14 11:20

    @hslx111
    RSS 更新是很慢的。呵呵。

    [回复]

  7. #7 JiaCheng 回复 | 引用 Post:2009-09-14 15:25

    给你一脚,让你记得我来了!

    [回复]

  8. #8 bolo 回复 | 引用 Post:2009-09-14 18:35

    写得真抽象,俺看书去

    [回复]

  9. #9 小明猪 回复 | 引用 Post:2009-09-14 23:36

    怎么这么久了才写select语句…这语句已经用了XXX遍了,不过exists语句我就是他奶奶的用不好,exists相当重要阿…. :-|

    [回复]

  10. #10 阿飞 回复 | 引用 Post:2010-05-21 23:24

    你很精通MySQL啊?呵呵!

    [回复]

  11. #11 simaopig 回复 | 引用 Post:2010-05-23 18:15

    @阿飞
    正是因为不会才写的。。呼。呵呵。工作中学习。

    [回复]

  12. #12 阿飞 回复 | 引用 Post:2010-05-24 03:07

    @simaopig
    :mrgreen: MySQL在企业中占有度有多大啊?感觉大部分企业用的都是Oracle……

    [回复]

  13. #13 simaopig 回复 | 引用 Post:2010-05-24 09:37

    @阿飞
    呵呵,JAVA一般是用的ORACLE,而PHP一般都用MySQL的。所以其占有度,很高。 :cool:

    [回复]

  14. #14 阿飞 回复 | 引用 Post:2010-05-24 13:03

    @simaopig
    ;-) :smile:

    [回复]

发表评论

:wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)