本节要点

集合的概念
查询单个列
查询多个列
查询所有列
按单个字段排序
按多个字段排序
限制返回结果
返回前M行
返回中间N行
返回后N行

集合的概念

在上节课我们学习了如何创建一张表,以及如何向表中插入数据。数据填充好了,就可用于查询和分析。这节课我们首先从查询部分列开始讲起,然后再讲一下怎么查询表里所有的列。对于查询出来的结果,有时候我们还需要按一定的规则排序,或者有时候我们并不需要表中的所有数据,那么我们如何返回需要的结果呢?这都是我们本节课要讲解的内容。

在课程之前,我们先来了解一下数学中的一个基本概念——集合。集合是由一个或多个确定的元素所构成的整体。集合有三个特性:确定性、互异性、无序性。

确定性:一个元素要么属于这个集合,要么不属于这个集合,或者说,集合里边的元素是确定的元素。

互异性:集合里的元素都是不相同的,比如说,对于一个整数的集合来说,1和1如果都存在于集合中则违反了互异性。

无序性:这一点比较关键,集合里的所有的元素,只跟这个元素本身有关,跟顺序没有关系。比如说,对于1、2、3这三个整数组成的一个集合来说,1、2、3是集合里的元素,跟1、2、3在集合里的先后顺序是没有关系的。1、2、3这个集合,跟3、2、1或者1、3、2这个集合是等价的,是同一个集合。这一点在数据库查询结果里边是比较重要的。

举个例子,深圳市第一初级中学所有的学生是一个大的集合,这个集合里边所有的元素就是所有的学生,这个学生在数学集合概念上来说,还可以分为一些子集。那么子集如何分呢?可以按不同的分类标准来分,比如男生做一个子集,女生做一个子集,初一、初二、初三的学生各做一个子集,年龄这块也可以做区分,分成年龄大和年龄小两个子集。所以,对于一个集合来说,划分子集的方法其实有很多种。

以上是集合的一些特性。

从集合中划分子集,其实跟我们从数据库的某一张表查出一部分数据是一样的,都需要回答两个基本的问题:从哪里查和查什么。

查询单个列

首先学一下查询部分列该怎么做?在数据库里边是使用SELECT这个关键字。语法如下:

SELECT 字段列表 FROM 表名

这个是最简单的SQL语句,它包含了SQL语句必备的两个部分:从哪里查以及查什么。表名指定了从哪里查,字段列表是我们要查询的东西。这个SQL语句的执行结果我们叫做结果集,结果集其实类似集合,符合集合的两个特点,确定性和无序性,唯一不同在于,数据库中查询出来的结果没有互异性,也就是说,结果集里的元素是可以相同的。还要注意的是,结果集的无序性,如果结果集返回的是多条数据,这个顺序其实是不确定的,同样的SQL语句,可能执行多次,结果集有时候是一样的,有时候又不一样。即使你多次执行的结果一样,也并不能认为数据的顺序就是那样固定不变的,因为随着我们对这张表做一些更新,做一些删除或者插入,表里边的数据的顺序是可能会变的。

下面进入实战练习。

我们来查询student表,把学生表里的所有学生的ID查出来,该怎么写呢?我们可以这样去写:

SELECT student_id FROM student;

就是这么简单,在from后指定表名,在SELECT后跟上要查询的字段。如果没有指定排序规则,即使当前看到的结果集好像是按某种顺序排好了,其实也是不能肯定的,并不保证每次执行结果都是这样的。后面我们会继续学习SQL语句排序相关的知识点。

查询多个列

与查询单个字段类型,可以使用如下语句查询多个字段:

SELECT student_id, student_name, gender FROM student;

在SELECT后面跟上要查询的字段,字段间用逗号分隔。

查询所有列

如果想查询表里边的所有字段怎么办?

我们很自然的想到可以在SELECT后面把表里的所有字段都列出来。但查询所有字段还有另外一种简写写法,就是用*代替表里边的所有字段,这样就不用把表里边的字段一个一个列出来。

SELECT * FROM student;

执行结果跟上面写出所有字段名的结果是一样的。用*号这种方式查询出来的结果集,字段顺序就是表结构上的字段顺序,如果想调整,比如你想要某个字段放前面,那就需要把该字段写出来,写到其他字段前面去。

推荐列出段名的写法,这种写法比较灵活,想要哪个字段在前面就哪个字段在前面,想要哪个字段就查询出来哪个字段,不需要哪个字段不写出来就可以了。

按单个字段排序

前面我们说了,没有指定排序规则的话,查询结果的顺序其实是随机的,如果你想要每次输出的结果集都按照一定的顺序查询出来,比如按照student_id排序,该如何操作呢?

可以使用关键字:ORDER BY … [ASC/DESC]

ORDER BY后面跟上字段名称,后面还可以指定是升序排序(ASC)还是降序排序(DESC)。语法如下:

SELECT 字段列表 FROM 表名 ORDER BY 字段1 [ASC/DESC], 字段2 [ASC/DESC]…;

有时候并不仅仅按一个字段排序,我们可以在第一个字段排序后面跟着第二个字段及其排序规则(升序/降序)。比如按学生的年龄,从小到大排序:

SELECT student_id, student_name, age FROM student ORDER BY age ASC;

ASC是默认的排序规则,可以省略不写,下面这种写法与上面是等价的。

SELECT student_id, student_name, age FROM student ORDER BY age;

这样查询出来的结果集就是一个有序的集合了。

按多个字段排序

上面的语句得出的结果我们可以看到有时候执行多次,结果可能不一样。原因是因为,同样年龄的多个同学,谁排在前谁排在后,就不一定了。比如,10岁同学的排序是随机的。那如果我们想要指定同样岁数的同学继续排序怎么办呢?比如说,再按姓名排序。

SELECT class_id, student_id, student_name, age FROM student ORDER BY age ASC,student_name ASC;

上面的排序表示,先按age升序排序,如果age相同,再按student_name升序排序。

下面再介绍一下排序的简写写法。其实可以用SELECT后面字段的顺序位置替换ORDER BY字段名。比如,上面的写法可以简写为:

SELECT class_id, student_id, student_name, age FROM student ORDER BY 1 ASC, 2 ASC;

当然,更简洁的写法是:

SELECT class_id, student_id, student_name, age FROM student ORDER BY 1,2;

不过,一般来说不太建议用字段位置替换字段名称来排序,因为有时候可能更换了字段位置,却忘了更改排序的位置数字,这样得到的结果集可能就不是我们想要的。

返回前M行

上面学习过的语句是把表的所有的记录都查出来,如果不想要所有记录,比如只想查前几行的数据怎么办呢?有两种关键字:TOP、LIMIT。语法如下:

SELECT TOP 10 字段列表 FROM 表名; --注意:Mysql不支持这种写法
SELECT 字段列表 FROM 表名 LIMIT 10;

上面两种写法,都是从表中随机返回10条数据。

一般在下面两种情况中使用的比较多:

表中数据量太大了,不想把所有数据都查出来,而只是想随便查看一下表中的数据大概长什么样子,每个字段是什么样的赋值;
一般与ORDER BY 关键字配合使用,返回按某些字段排序后的前几行。

返回中间N行

可是,如果我们不是想返回前几行,而是想取到中间几行的数据,这种情况怎么处理呢?仍然可以使用关键字LIMIT,语法如下:

LIMIT M OFFSET N (从第N行开始,返回M行记录)

常见的写法有两种:

SELECT 字段列表 FROM 表名 LIMIT M OFFSET N;
SELECT 字段列表 FROM 表名 LIMIT N,M;

上面这两种写法,都从第N行开始,返回M行数据。注意:这里的第N行是从0开始算起的。

LIMIT关键字一般与ORDER BY关键字配合使用,按M行为一页,返回某一个分页的记录。

SELECT class_id, student_id, student_name, gender, birth_day, age
FROM student
ORDER BY 6 ASC, 3 ASC
LIMIT 20,10;

显然,SELECT 字段列表 FROM 表名 LIMIT 0,10; 等价于SELECT 字段列表 FROM 表名 LIMIT 10;

返回后N行

那怎么返回后几行呢?常用的关键字有下面三个:

关键字:TOP、LIMIT、ORDER BY

SQL语言中,没有返回后几行的专用写法,一般转换为按相反的排序方式取出前几行而变相地实现返回后几行。

可以执行下面这个SQL语句,分析下执行结果,这里涉及的子查询后面会详细讲。

SELECT * FROM
(
    SELECT TOP 5 *
    FROM student
    ORDER BY student_id DESC
) a
ORDER BY student_id ASC

课后习题:

1、对于第6课课后习题中的论坛注册用户表,请编写SQL完成以下查询。

(1)、请查询出所有注册用户的用户名和手机号。

(2)、请按注册时间升序排序查询注册用户的用户名、所在地省市区、注册时间。

(3)、请查询出第100位注册的用户信息。

(4)、请查询出前100位注册的用户信息。

(5)、请查询出第100-200位注册的用户信息。

(6)、请查询出最近刚注册的100位用户信息。

(7)、请查询出所有注册用户的信息,并将相同的省市区用户显示在一起。

picture loss