• Post author:
  • Post category:mysql
  • Post comments:0评论

一、简介

  DQL即数据查询语言,用于实现对数据的查询操作。主要语句 SELECT 查询语句,是数据库中应用最广泛、最重要的语句之一,也是我们使用频率最高的。

  SELECT 查询语句的基本语法:

    select [ all|distinct ] 表达式列表
    from 表列表
    [ where 查询条件 ]
    [ group by 分组列名表 ]
    [ having 逻辑表达式 ]
    [ order by 排序列表名[asc|desc] ]
    [ limit {[offset,] row_count | row_count OFFSET offset}]

  SELECT 语句中的子句顺序非常重要,可以省略任选子句(方括号中的子句),但是这些子句在使用时必须按规定的顺序使用。下面会对上述子句语法详细解释。

二、select独立使用

1、查询系统变量

数据库配置文件中的配置都可以通过这个方式查询

select @@port;          # 查询数据库监听端口
select @@basedir;       # 查询数据库软件安装目录
select @@datadir;       # 查询数据库数据存放目录

以上只列出部分,可以通过以下方式查询数据库其它的系统变量:
show variables;
show variables like 'port'

2、查询函数

列出部分常用

select version();
select user();
select now();

3、字符串拼接

mysql> select concat('hello');
+-----------------+
| concat('hello') |
+-----------------+
| hello           |
+-----------------+

mysql> select concat(user,'@',host) from mysql.user;
+-------------------------+
| concat(user,'@',host)   |
+-------------------------+
| mysql.session@localhost |
| mysql.sys@localhost     |
| root@localhost          |
+-------------------------+

4、数据类型的转换

  数据转换可以用到MySQL自带的函数convert() 或者 cast()。当然数据类型转换函数肯定不止这两个。
  语法格式:
    convert( 表达式,数据类型 )
    cast( 表达式 as 数据类型 )
  注意以上两个函数可转换的类型有 字符串char、日期date、时间time、日期时间datetime、浮点型decimal、整数signed、无符号整数unsigned。
  例如:

mysql>  select convert('3.14',char(1));
+-------------------------+
| convert('3.14',char(1)) |
+-------------------------+
| 3                       |
+-------------------------+

mysql>  select convert('3.14',decimal);
+-------------------------+
| convert('3.14',decimal) |
+-------------------------+
|                       3 |
+-------------------------+

mysql>  select convert('3.14',decimal(2,1));
+------------------------------+
| convert('3.14',decimal(2,1)) |
+------------------------------+
|                          3.1 |
+------------------------------+

mysql>  select cast('3.14' as decimal(2,1));
+------------------------------+
| cast('3.14' as decimal(2,1)) |
+------------------------------+
|                          3.1 |
+------------------------------+

三、准备SELECT查询演示表

[root@db03 ~]# wget https://www.cpweb.top/wp-content/uploads/2020/10/Education.zip
[root@db03 ~]# unzip Education.zip
[root@db03 ~]# mysql -uroot -p < Education.sql

  我们来看下 Education 库中三张表的结构。

mysql> use Education;
mysql> desc student;
+-----------+-------------------+------+-----+---------+-------+
| Field     | Type              | Null | Key | Default | Extra |
+-----------+-------------------+------+-----+---------+-------+
| Sid       | char(10)          | NO   | PRI | NULL    |       |    # 学号,主键
| Sname     | char(8)           | NO   |     | NULL    |       |    # 姓名
| Sex       | enum('男','女')   | NO   |     | NULL    |       |    # 性别
| Birthdate | date              | YES  |     | NULL    |       |    # 出生日期   
| Specialty | varchar(30)       | NO   |     | NULL    |       |    # 专业
| AScores   | decimal(4,1)      | YES  |     | NULL    |       |    # 录取分数
+-----------+-------------------+------+-----+---------+-------+

mysql> desc course;
+--------+--------------+------+-----+---------+----------------+
| Field  | Type         | Null | Key | Default | Extra          |
+--------+--------------+------+-----+---------+----------------+
| No     | int(11)      | NO   | MUL | NULL    | auto_increment |   # 编号,自增列
| Cid    | char(8)      | NO   | PRI | NULL    |                |   # 课程代码,主键
| Cname  | varchar(20)  | NO   |     | NULL    |                |   # 课程名称
| Credit | decimal(3,1) | NO   |     | NULL    |                |   # 学分
+--------+--------------+------+-----+---------+----------------+

mysql> desc sc;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| Sid    | char(10)     | NO   | PRI | NULL    |       |    # 学号,主键
| Cid    | char(8)      | NO   | PRI | NULL    |       |    # 课程代码,主键
| Scores | decimal(4,1) | YES  |     | NULL    |       |    # 课程分数
+--------+--------------+------+-----+---------+-------+

四、SELECT子句投影查询

  投影查询简单说就是选择特定的列的查询。

1、投影某些列查询

  前面基本语法中提到的表达式列表:一个用逗号分隔的表达式列表,表达式可以由列名、常量、函数和运算符构成。

mysql> select Sid,Sname,Sex,Specialty,AScores      # 投影列Sid、Sname、Sex、specialty,ascores
    -> from student                                # 查询的表
    -> where sex='男';                             # 查询条件。where子句后面会详细讲到。

可以使用通配符'*'投影所有列
mysql> select * from student where sex='男';

2、消除重复数据行

  相关的有两个关键字 all 和 distinct。all(默认)关键字将保留查询结果集中的所有数据行;distinct 可以消除查询结果集中的重复数据行。
  例如,我们需要统计学生表 student 中各专业的名称,如果我们只投影 specialty 列查询,那么就会出现许多重复行,这不是我们希望得到的,这是就可以使用 distinct 来消除重复的专业名称。

mysql> select distinct specialty from student;
+-----------------------+
| specialty             |
+-----------------------+
| 计算机应用技术        |
| 计算机信息管理        |
| 软件技术              |
| 计算机网络技术        |
+-----------------------+

3、使用表达式计算列值

  在SELECT子句中可以使用加(+)、减(-)、乘(*)、除(/)、取模(%)等运算符及各种函数进行运算,通过表达式的计算来获取查询结果的列值。
  假设每18学时计一分,现要统计课程表 course 中每门课程修满学分需要多少学时。

mysql> select cname,credit,credit*18 from course limit 4;       # 'limit 4' 表示显示查询结果集的前四行数据
+-----------------------------+--------+-----------+
| cname                       | credit | credit*18 |
+-----------------------------+--------+-----------+
| 微机组装与维护              |    2.0 |      36.0 |
| 操作系统安装与使用          |    2.0 |      36.0 |
| 计算机基础                  |    3.5 |      63.0 |
| 面向过程程序设计            |   10.0 |     180.0 |
+-----------------------------+--------+-----------+

  如果要对计算后的数据取整,并在其后添加单位学时,可以使用 concat() 和 convert() 两个函数。同时我们可以看到计算出来学时的那一列的列名是表达式本身,我们可以在表达式后使用 as 自定义列名。

mysql> select cname,credit,concat(convert(credit*18,decimal(5,0)),'学时') as '总学时' from course limit 4;
+-----------------------------+--------+-----------+
| cname                       | credit | 总学时    |
+-----------------------------+--------+-----------+
| 微机组装与维护              |    2.0 | 36学时    |
| 操作系统安装与使用          |    2.0 | 36学时    |
| 计算机基础                  |    3.5 | 63学时    |
| 面向过程程序设计            |   10.0 | 180学时   |
+-----------------------------+--------+-----------+

4、聚合函数

  聚合函数的参数为列名或者包含列名的表达式,主要功能是对表在指定列名表达式的值上进行纵向统计和计算,所以也被称为列函数。在SELECT 查询语句中,常用的列函数如下:
   • count:统计列中选取的项目个数或者查询输出的行数。
   • sum:计算指定数值型列名表达式的总和。
   • avg:计算指定数值型列名表达式的平均值。
   • max: 求出指定的数值、字符或者日期型列名表达式的最大值。
   • max: 求出指定的数值、字符或者日期型列名表达式的最小值。

(1) 从学生表 student 中统计男生的人数
mysql> select count(*) as '男生人数' from student where sex='男';
+--------------+
| 男生人数     |
+--------------+
|            8 |
+--------------+

(2) 从学生表 student 中统计专业的个数
mysql> select count(distinct specialty) as '专业个数' from student;
+--------------+
| 专业个数     |
+--------------+
|            4 |
+--------------+

(3) 从学生表中统计出学生的总数、录取分数的最高分、最低分、总分和平均分
mysql> select count(*) as '总人数',max(ascores) as '最高分',
       min(ascores) as '最低分',sum(ascores) as '总分',
       avg(ascores) as '平均分'
       from student;
+-----------+-----------+-----------+--------+-----------+
| 总人数    | 最高分    | 最低分    | 总分   | 平均分    |
+-----------+-----------+-----------+--------+-----------+
|        21 |     408.0 |     312.0 | 7481.6 | 356.26667 |
+-----------+-----------+-----------+--------+-----------+

五、FROM子句连接查询

  FROM子句用来指定要查询的表,如果指定了一个以上表,则计算它们之间的笛卡尔乘积。

1、指定表

  例如,现要从 Education 数据库查询出学生的学号、姓名、所选课程名和成绩信息。其中学号 ‘sid’ 来自学生表 ‘student’ 或者选课表 ‘sc’,学生姓名 ‘sname’ 来自学生表 ‘student’ ,课程名 ‘cname’ 来自课程表 ‘course’,成绩 ‘scores’ 来自选课表 ‘sc’。

mysql> select student.sid,sname,cname,scores
    -> from student,sc,course                               # 三个表进行笛卡尔积
    -> where student.sid=sc.sid and sc.cid=course.cid;      # 等值连接条件
+------------+-----------+---------------------+--------+
| sid        | sname     | cname               | scores |
+------------+-----------+---------------------+--------+
| 2011216001 | 赵成刚    | 微机组装与维护      |   96.0 |
| 2011216001 | 赵成刚    | 操作系统安装与使用  |   80.0 |
| 2011216002 | 李婧      | 微机组装与维护      |   67.0 |
| 2011216003 | 郭洪亮    | 计算机基础          |   78.0 |
| 2011216003 | 郭洪亮    | 面向过程程序设计    |   87.0 |
| 2011216003 | 郭洪亮    | 数据库开发与维护    |   85.0 |
| 2011216111 | 吴秋娟    | 数据库开发与维护    |   89.0 |
| 2011216111 | 吴秋娟    | 面向对象程序设计    |   90.0 |
| 2012216089 | 姜丽丽    | 微机组装与维护      |   58.0 |
+------------+-----------+---------------------+--------+

  FROM 子句中表的前后顺序不影响查询结果。在 WHERE 子句描述等值条件的逻辑表达式中,列名要用基本表名来标识,如 ‘student.sid=sc.sid’,表示选择条件是 学生表’student’ 的学号 ‘sid’ 等于选课表 ‘sc’ 的学号 ‘sid’。
  对于 SELECT 子句投影的列,在列名不会混淆的情况下可以不加所属表来标识,如 ‘sname’ 列只属于学生表 ‘student’、’cname’ 列只属于课程表 ‘course’。
  如果所连接的表中存在同名列,则要用表名来标识,如 ‘student.sid’ 或者 ‘sc.sid’,如果不用表名标识,mysql就不知道 ‘sid’ 是属于 ‘sc’ 还是 ‘student’ 表,执行查询时就会报错,报错为列名 ‘sid’ 不明确。

2、指定表的临时别名

  上面我们提到了as自定义列名,同样用在 FROM 子句可以为表指定临时别名,别名可以简化表名,还可以实现自连接。
  例如,以上例为准,为表 ‘student’、’course’、’sc’ 指定别名为x、y、z以简化表名。

mysql> select x.sid,sname,cname,scores 
    -> from student as x,sc as y,course as z 
    -> where x.sid=y.sid and y.cid=z.cid; 
+------------+-----------+---------------------+--------+
| sid        | sname     | cname               | scores |
+------------+-----------+---------------------+--------+
| 2011216001 | 赵成刚    | 微机组装与维护      |   96.0 |
| 2011216001 | 赵成刚    | 操作系统安装与使用  |   80.0 |
| 2011216002 | 李婧      | 微机组装与维护      |   67.0 |
| 2011216003 | 郭洪亮    | 计算机基础          |   78.0 |
| 2011216003 | 郭洪亮    | 面向过程程序设计    |   87.0 |
| 2011216003 | 郭洪亮    | 数据库开发与维护    |   85.0 |
| 2011216111 | 吴秋娟    | 数据库开发与维护    |   89.0 |
| 2011216111 | 吴秋娟    | 面向对象程序设计    |   90.0 |
| 2012216089 | 姜丽丽    | 微机组装与维护      |   58.0 |
+------------+-----------+---------------------+--------+

  我们再来看下如果利用别名实现自连接,例如从选课表 ‘sc’ 中查询出选了至少两门课程的学生。

mysql> select distinct x.sid as '学号' 
    -> from sc x,sc y                           # 为'sc'表指定两个不同别名,实现自连接
    -> where x.sid=y.sid and x.cid<>y.cid;      # '<>' 等效于 '!=',即不等于的意思
+------------+
| 学号       |
+------------+
| 2011216001 |
| 2011216003 |
| 2011216111 |
+------------+

  注:自连接通俗说就是和自己进行连接查询,给同一张表指定两个不同的别名,然后附上连接条件。后面文章会详细介绍到。

六、WHERE子句选择查询

  WHERE 子句用于选择操作,定义了表中的行要满足条件(逻辑表达式为真)才能向查询结果集提供数据,否则数据将不被采用。此外 WHERE 子句的还用在 DELETE 和 UPDATE 语句中定义表中被删除和修改的行。

1、关系运算符

  在 WHERE 子句中,可以将各种关系运算符与列名、常量或者函数一起构成关系表达式,用关系表达式描述一些简单的条件,从而实现对表的选择查询。主要运算符有:=(等于)、<>(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)
  例如,从学生表 ‘student’ 中查询录取分数大于400分的学生。

mysql> select * from student where ascores>=400;
+------------+-----------+-----+------------+-----------------------+---------+
| Sid        | Sname     | Sex | Birthdate  | Specialty             | AScores |
+------------+-----------+-----+------------+-----------------------+---------+
| 2011216001 | 赵成刚    | 男  | 1992-05-05 | 计算机应用技术        |  405.0  |
| 2011216111 | 吴秋娟    | 女  | 1992-08-05 | 软件技术              |  408.0  |
+------------+-----------+-----+------------+-----------------------+---------+

  从学生表 ‘student’ 中查询前五人现在的年龄。

mysql> select sname,
    -> convert(date_format(now(),'%Y'),signed)-convert(date_format(Birthdate,'%Y'),signed) as '年龄' 
    -> from student 
    -> limit 5;
+-----------+--------+
| sname     | 年龄   |
+-----------+--------+
| 赵成刚    |     28 |
| 李婧      |     28 |
| 郭洪亮    |     28 |
| 吕珊珊    |     27 |
| 高全英    |     27 |
+-----------+--------+

2、逻辑运算符

  在 WHERE 子句中,可以使用逻辑运算符把各个查询条件连接起来,从而实现比较复杂的选择查询。主要逻辑运算符有:not(非)、and(与)、or(或)
  例如,从学生表 ‘student’ 中分别查询专业为软件技术或者计算机网络技术的男女学生。

mysql> select * from student where sex='女' and (specialty='软件技术' or specialty='计算机网络技术');
+------------+-----------+-----+------------+-----------------+---------+
| Sid        | Sname     | Sex | Birthdate  | Specialty       | AScores |
+------------+-----------+-----+------------+-----------------+---------+
| 2011216111 | 吴秋娟    | 女  | 1992-08-05 | 软件技术        |   408.0 |
| 2011216115 | 张欣欣    | 女  | 1992-04-12 | 计算机网络技术  |   315.5 |
| 2011216117 | 孟霞      | 女  | 1993-01-11 | 计算机网络技术  |   334.0 |
| 2012216056 | 刘明明    | 女  | 1994-10-09 | 软件技术        |   357.0 |
| 2012216058 | 王婷      | 女  | 1994-04-13 | 软件技术        |   356.0 |
| 2012216089 | 姜丽丽    | 女  | 1994-10-18 | 计算机网络技术  |   368.0 |
+------------+-----------+-----+------------+-----------------+---------+
6 rows in set (0.00 sec)

mysql> select * from student where not sex='女' and (specialty='软件技术' or specialty='计算机网络技术');
+------------+-----------+-----+------------+------------------+---------+
| Sid        | Sname     | Sex | Birthdate  | Specialty        | AScores |
+------------+-----------+-----+------------+------------------+---------+
| 2011216007 | 张锋      | 男  | 1992-09-03 | 软件技术         |   389.0 |
| 2011216112 | 穆金华    | 男  | 1992-10-06 | 软件技术         |   365.0 |
| 2012216057 | 孙政先    | 男  | 1993-05-16 | 软件技术         |   362.5 |
| 2012216088 | 吕文昆    | 男  | 1993-09-03 | 计算机网络技术   |   335.0 |
+------------+-----------+-----+------------+----------------------------+

3、范围运算符

  在 WHERE 子句中,可以使用范围运算符指定查询数据的范围。范围运算符有 between 和 not between。
  语法格式:
    • between 开始值 and 结束值:等价于 ‘列名>=开始值 and 列名<=结束值’
    • not between 开始值 and 结束值:等价于 ‘列名<开始值 or 列名>结束值’

  例如,从学生表 ‘student’ 中查询录取分数在380分到400分区间的学生。

mysql> select * from student where ascores between 380 and 400;
+------------+-----------+-----+------------+--------------------+---------+
| Sid        | Sname     | Sex | Birthdate  | Specialty          | AScores |
+------------+-----------+-----+------------+--------------------+---------+
| 2011216002 | 李婧      | 女  | 1992-01-06 | 计算机应用技术     |   395.5 |
| 2011216005 | 高全英    | 女  | 1993-07-05 | 计算机信息管理     |   387.5 |
| 2011216007 | 张锋      | 男  | 1992-09-03 | 软件技术           |   389.0 |
+------------+-----------+-----+------------+--------------------+---------+

4、模式匹配运算符

  在 WHERE 子句中,可以使用模式匹配运算符 like 去实现对表的模糊查询。
  语法格式:
    列名 [not] like 字符串(含通配符)
  通配符"_"代表一个任意字符,"%"代表任意多个字符。例如,从学生表 ‘student’ 中分别查询李姓学生、名字中包含洪字的学生和两个字名字的学生。

mysql> select * from student where Sname like '李%';
+------------+--------+-----+------------+--------------------+---------+
| Sid        | Sname  | Sex | Birthdate  | Specialty          | AScores |
+------------+--------+-----+------------+--------------------+---------+
| 2011216002 | 李婧   | 女  | 1992-01-06 | 计算机应用技术     |   395.5 |
| 2012216030 | 李岩   | 男  | 1994-09-03 | 计算机信息管理     |   316.0 |
+------------+--------+-----+------------+--------------------+---------+

mysql> select * from student where Sname like '%洪%';
+------------+-----------+-----+------------+-----------------------+---------+
| Sid        | Sname     | Sex | Birthdate  | Specialty             | AScores |
+------------+-----------+-----+------------+-----------------------+---------+
| 2011216003 | 郭洪亮    | 男  | 1992-04-12 | 计算机应用技术        |   353.0 |
+------------+-----------+-----+------------+-----------------------+---------+

mysql> select * from student where Sname like '__';
+------------+--------+-----+------------+-------------------+---------+
| Sid        | Sname  | Sex | Birthdate  | Specialty         | AScores |
+------------+--------+-----+------------+-------------------+---------+
| 2011216002 | 李婧   | 女  | 1992-01-06 | 计算机应用技术    |   395.5 |
| 2011216006 | 赫莎   | 女  | 1991-08-03 | 计算机信息管理    |   372.0 |
| 2011216007 | 张锋   | 男  | 1992-09-03 | 软件技术          |   389.0 |
| 2011216117 | 孟霞   | 女  | 1993-01-11 | 计算机网络技术    |   334.0 |
| 2012216009 | 程鹏   | 男  | 1993-08-03 | 计算机应用技术    |   342.6 |
| 2012216030 | 李岩   | 男  | 1994-09-03 | 计算机信息管理    |   316.0 |
| 2012216031 | 周梅   | 女  | 1994-06-03 | 计算机信息管理    |   312.0 |
| 2012216032 | 管芬   | 女  | 1994-10-11 | 计算机信息管理    |   326.0 |
| 2012216058 | 王婷   | 女  | 1994-04-13 | 软件技术          |   356.0 |
+------------+--------+-----+------------+-------------------+---------+

5、列表运算符

  在 WHERE 子句中,可以使用列表运算符 in 将列表中的值或者子查询的值作为筛选条件。
  语法格式:
    列名 [not] in(列表|子查询)
  例如,从学生表 ‘student’ 中查询学号为2011216007和2012216089的学生信息。

mysql> select * from student where sid in('2011216007','2012216089');
+------------+-----------+-----+------------+-------------------+---------+
| Sid        | Sname     | Sex | Birthdate  | Specialty         | AScores |
+------------+-----------+-----+------------+-------------------+---------+
| 2011216007 | 张锋      | 男  | 1992-09-03 | 软件技术          |   389.0 |
| 2012216089 | 姜丽丽    | 女  | 1994-10-18 | 计算机网络技术    |   368.0 |
+------------+-----------+-----+------------+-------------------+---------+

6、空值运算符

  在 WHERE 子句中,可以使用空值运算符将列值为空作为筛选条件。
  语法格式:
    列名 is [not] null
  例如,从Education数据库中查询课程成绩没有登记的学生信息(先随便把一个学生的课程成绩改为空)。

mysql> update sc set scores=null where sid='2011216001';

mysql> select x.sid,sname,cname,scores 
       from student x,sc y,course z 
       where x.sid=y.sid and y.cid=z.cid 
       and scores is null;
+------------+-----------+----------------------+--------+
| sid        | sname     | cname                | scores |
+------------+-----------+----------------------+--------+
| 2011216001 | 赵成刚    | 微机组装与维护       |   NULL |
| 2011216001 | 赵成刚    | 操作系统安装与使用   |   NULL |
+------------+-----------+----------------------+--------+

七、GROUP BY 子句分组统计查询

  GROUP BY 子句可以与列名或者聚合函数配合实现分组统计。前面的例子中的聚合函数都是对整个表中的数据进行统计计算,但是实际应用中往往需要根据某列的值进行分组统计与汇总。如下示例:
  从学生表 ‘student’ 中查询各专业学生平均录取分数。

mysql> select specialty as '专业',
       convert(avg(ascores),decimal(4,1)) as '平均分' 
       from studennt 
       group by specialty;
+--------------------+-----------+
| 专业               | 平均分    |
+--------------------+-----------+
| 计算机信息管理     |     344.4 |
| 计算机应用技术     |     365.0 |
| 计算机网络技术     |     338.1 |
| 软件技术           |     372.9 |
+--------------------+-----------+

  从学生表 ‘student’ 中查询各专业学生的总数。

mysql> select specialty as '专业',count(*) as '人数'  
       from student 
       group by specialty;
+--------------------+-------+
| 专业               | 人数  |
+--------------------+-------+
| 计算机信息管理     |     6 |
| 计算机应用技术     |     5 |
| 计算机网络技术     |     4 |
| 软件技术           |     6 |
+--------------------+-------+

  从学生表 ‘student’ 和选课表 ‘sc’ 中统计每位学生的总成绩,要求显示学生学号、姓名和总成绩。

mysql> select sc.sid,sname,sum(scores) as '总成绩'
       from sc,student
       where sc.sid=student.sid
       group by sc.sid;
+------------+-----------+----------+
| sid        | sname     | 总成绩   |
+------------+-----------+----------+
| 2011216001 | 赵成刚    |    176.0 |
| 2011216002 | 李婧      |     67.0 |
| 2011216003 | 郭洪亮    |    250.0 |
| 2011216111 | 吴秋娟    |    179.0 |
| 2012216089 | 姜丽丽    |     58.0 |
+------------+-----------+----------+

八、HAVING 子句限定查询

  HAVING 子句可以配合GROUP BY筛选统计结果。值得一提的是 HAVING 子句的逻辑表达式可以包含聚合函数,但是WHERE 子句的逻辑表达式不可以。
  例如,从学生表 ‘student’ 和选课表 ‘sc’ 中查询总成绩超过150分学生的学号、姓名和总成绩。

mysql> select sc.sid,sname,sum(scores) as '总成绩'                                         
       from sc,student
       where sc.sid=student.sid
       group by sc.sid
       having sum(scores)>150;
+------------+----------+----------+
| sid        | sname    | 总成绩   |
+------------+----------+----------+
| 2011216001 | 赵成刚   |   176.0  |
| 2011216003 | 郭洪亮   |   250.0  |
| 2011216111 | 吴秋娟   |   179.0  |
+------------+----------+----------+

九、ORDER BY 子句排序查询

  ORDER BY 子句可以对查询结果进行升序(ASC 默认)或者降序(DESC)排序。如果ORDER BY 子句后面是一个列名表达式表,则系统将根据各列的次序决定排序的优先级,然后排序。
  从学生表 ‘student’ 和选课表 ‘sc’ 中统计每位学生的总成绩,并将结果按照总成绩降序排序。

mysql> select sc.sid,sname,sum(scores) as '总成绩'
       from sc,student
       where sc.sid=student.sid
       group by sc.sid
       order by sum(scores) desc;
+------------+-----------+-----------+
| sid        | sname     | 总成绩    |
+------------+-----------+-----------+
| 2011216003 | 郭洪亮    |    250.0  |
| 2011216111 | 吴秋娟    |    179.0  |
| 2011216001 | 赵成刚    |    176.0  |
| 2011216002 | 李婧      |     67.0  |
| 2012216089 | 姜丽丽    |     58.0  |
+------------+-----------+-----------+

  从Education 数据库中查询每个学生的选课门数并按选课门数的多少进行升序排序。

mysql> select sc.sid,sname,count(*) as '选课门数' 
       from student,sc
       where student.sid=sc.sid
       group by sc.sid
       order by count(*);
+------------+----------+-----------+
| sid        | sname    | 选课门数  |
+------------+----------+-----------+
| 2011216002 | 李婧     |        1  |
| 2012216089 | 姜丽丽   |        1  |
| 2011216001 | 赵成刚   |        2  |
| 2011216111 | 吴秋娟   |        2  |
| 2011216003 | 郭洪亮   |        3  |
+------------+----------+-----------+

  从学生表 ‘student’ 中查询出软件技术专业学生的信息,并按照性别升序和入学成绩降序排序。

mysql> select sname,sex,specialty,ascores 
       from student 
       where specialty='软件技术' 
       order by sex asc,ascores desc;
+-----------+-----+--------------+---------+
| sname     | sex | specialty    | ascores |
+-----------+-----+--------------+---------+
| 张锋      | 男  | 软件技术     |   389.0 |
| 穆金华    | 男  | 软件技术     |   365.0 |
| 孙政先    | 男  | 软件技术     |   362.5 |
| 吴秋娟    | 女  | 软件技术     |   408.0 |
| 刘明明    | 女  | 软件技术     |   357.0 |
| 王婷      | 女  | 软件技术     |   356.0 |
+-----------+-----+--------------+---------+

十、LIMIT 子句

  LIMIT 子句用于限定查询结果集返回的行数。
  语法格式:
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
  LIMIT 可以指定一个或两个数字参数,参数必须是一个整数常量。如果指定一个参数,可以说就是返回前几行。如果指定两个参数,第一个参数指定第一个返回记录行的偏移量offset(从0开始),第二个参数指定返回记录行的最大数目。
  例如,查询学生表 ‘student’ 表的前4行。

mysql> select * from student limit 4;
+------------+-----------+-----+------------+-----------------------+---------+
| Sid        | Sname     | Sex | Birthdate  | Specialty             | AScores |
+------------+-----------+-----+------------+-----------------------+---------+
| 2011216001 | 赵成刚    | 男  | 1992-05-05 | 计算机应用技术        |   405.0 |
| 2011216002 | 李婧      | 女  | 1992-01-06 | 计算机应用技术        |   395.5 |
| 2011216003 | 郭洪亮    | 男  | 1992-04-12 | 计算机应用技术        |   353.0 |
| 2011216004 | 吕珊珊    | 女  | 1993-10-11 | 计算机信息管理        |   353.0 |
+------------+-----------+-----+------------+-----------------------+---------+

mysql> select * from student limit 0,4;
+------------+-----------+-----+------------+-----------------------+---------+
| Sid        | Sname     | Sex | Birthdate  | Specialty             | AScores |
+------------+-----------+-----+------------+-----------------------+---------+
| 2011216001 | 赵成刚    | 男  | 1992-05-05 | 计算机应用技术        |   405.0 |
| 2011216002 | 李婧      | 女  | 1992-01-06 | 计算机应用技术        |   395.5 |
| 2011216003 | 郭洪亮    | 男  | 1992-04-12 | 计算机应用技术        |   353.0 |
| 2011216004 | 吕珊珊    | 女  | 1993-10-11 | 计算机信息管理        |   353.0 |
+------------+-----------+-----+------------+-----------------------+---------+

  查询学生表 ‘student’ 表的4行到8行。

mysql> select * from student limit 3,5;
+------------+-----------+-----+------------+-----------------------+---------+
| Sid        | Sname     | Sex | Birthdate  | Specialty             | AScores |
+------------+-----------+-----+------------+-----------------------+---------+
| 2011216004 | 吕珊珊    | 女  | 1993-10-11 | 计算机信息管理        |   353.0 |
| 2011216005 | 高全英    | 女  | 1993-07-05 | 计算机信息管理        |   387.5 |
| 2011216006 | 赫莎      | 女  | 1991-08-03 | 计算机信息管理        |   372.0 |
| 2011216007 | 张锋      | 男  | 1992-09-03 | 软件技术              |   389.0 |
| 2011216111 | 吴秋娟    | 女  | 1992-08-05 | 软件技术              |   408.0 |
+------------+-----------+-----+------------+-----------------------+---------+

十一、保存查询结果到新表

mysql> create table new_student1(select sname,sex from student where sex='男' limit 2);
mysql> select * from new_student1;
+-----------+-----+
| sname     | sex |
+-----------+-----+
| 赵成刚    | 男  |
| 郭洪亮    | 男  |
+-----------+-----+

mysql> create table new_student2 as select sname,sex from student where sex='男' limit 2;
mysql> select * from new_student2;
+-----------+-----+
| sname     | sex |
+-----------+-----+
| 赵成刚    | 男  |
| 郭洪亮    | 男  |
+-----------+-----+


  文章大部分内容来源:《 SQL Server 2008 R2 数据库技术及应用(第3版)》。以上内容基于数据库版本mysql 5.7.28。

发表评论

验证码: + 44 = 51