一、SELECT介绍

1.1 SELECT

SELECT是数据库四大基本操作的一种,用于查询表中的数据信息。

基本的查询语法为:SELECT 列1, 列2, ... FROM 表,表示从表中取出对应的列。

SELECT语句的用法多种多样,并且还有很多高级的操作(如排序、分组以及联合等等),是增删改查四种基本操作中用法最多也运用最广的命令。

1.2 测试数据

创建测试表stu_info,所有的测试将会在这张表上进行:

CREATE TABLE `stu_info` (
  `stu_id` int(12) unsigned zerofill NOT NULL AUTO_INCREMENT,
  `stu_name` varchar(255) NOT NULL DEFAULT '',
  `age` tinyint(4) NOT NULL,
  `classno` tinyint(4) NOT NULL,
  `city` varchar(255) NOT NULL,
  PRIMARY KEY (`stu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

表中数据:

+--------------+-----------+-----+---------+----------+
| stu_id       | stu_name  | age | classno | city     |
+--------------+-----------+-----+---------+----------+
| 000000000001 | maqian    |  24 |       1 | changsha |
| 000000000002 | xiaoming  |  19 |       2 | shanghai |
| 000000000003 | xiaohua   |  23 |       2 | shenzhen |
| 000000000004 | xiaobai   |  22 |       3 | shenzhen |
| 000000000005 | xiaowang  |  19 |       4 | hunan    |
| 000000000006 | xiaozhou  |  20 |       3 | wuhan    |
| 000000000007 | xiaoli    |  20 |       1 | changsha |
| 000000000008 | xiaopeng  |  23 |       1 | changsha |
| 000000000009 | xiaozheng |  22 |       1 | fujian   |
+--------------+-----------+-----+---------+----------+

二、使用SELECT查询数据

2.1 查询单列数据

查询所有的学生名字:

SELECT stu_name FROM stu_info;

结果:

+-----------+
| stu_name  |
+-----------+
| maqian    |
| xiaoming  |
| xiaohua   |
| xiaobai   |
| xiaowang  |
| xiaozhou  |
| xiaoli    |
| xiaopeng  |
| xiaozheng |
+-----------+
注意事项:查询时,如果没有明确指定排序对象,返回的数据中顺序没有特殊意义,每次返回的顺序可能都不同。只要保证每次返回的行数是一样的就是正常。

2.2 查询多个列

查询所有学生的名字及年龄信息,查询多列时,不同列之间使用,隔开:

SELECT stu_name, age FROM stu_info;

结果:

+-----------+-----+
| stu_name  | age |
+-----------+-----+
| maqian    |  24 |
| xiaoming  |  19 |
| xiaohua   |  23 |
| xiaobai   |  22 |
| xiaowang  |  19 |
| xiaozhou  |  20 |
| xiaoli    |  20 |
| xiaopeng  |  23 |
| xiaozheng |  22 |
+-----------+-----+

2.3 查询所有列

使用通配符*表示查询所有列:

SELECT * FROM stu_info;

结果:

+--------------+-----------+-----+---------+----------+
| stu_id       | stu_name  | age | classno | city     |
+--------------+-----------+-----+---------+----------+
| 000000000001 | maqian    |  24 |       1 | changsha |
| 000000000002 | xiaoming  |  19 |       2 | shanghai |
| 000000000003 | xiaohua   |  23 |       2 | shenzhen |
| 000000000004 | xiaobai   |  22 |       3 | shenzhen |
| 000000000005 | xiaowang  |  19 |       4 | hunan    |
| 000000000006 | xiaozhou  |  20 |       3 | wuhan    |
| 000000000007 | xiaoli    |  20 |       1 | changsha |
| 000000000008 | xiaopeng  |  23 |       1 | changsha |
| 000000000009 | xiaozheng |  22 |       1 | fujian   |
+--------------+-----------+-----+---------+----------+
使用*来输出所有列时,会严重降低检索和应用程序的性能。大部分时候,尽量少使用用通配符,明确自己所需要的列。

2.4 去除重复数据

在查询时,可以通过DISTINCT关键字来剔除重复的行。如查询所有的班级(不重复):

SELECT DISTINCT classno FROM stu_info;

结果:

+---------+
| classno |
+---------+
|       1 |
|       2 |
|       3 |
|       4 |
+---------+

当对多个关键字使用DISTINCT时,只有所有列都相同才会被认为是重复的,其中某个字段相同并不会认为是同一个行:

SELECT DISTINCT classno, city FROM stu_info;

上面的数据中,有多个classno=1并且city=changsha的结果,使用DISTINCT之后,这些重复的行被剔除了,而同样classno=但是city=fujian的记录却依然存在:

+---------+----------+
| classno | city     |
+---------+----------+
|       1 | changsha |
|       2 | shanghai |
|       2 | shenzhen |
|       3 | shenzhen |
|       4 | hunan    |
|       3 | wuhan    |
|       1 | fujian   |
+---------+----------+

2.5 限制结果

使用LIMIT关键字可以限制输出的结果数量,语法格式为:

  1. LIMIT N:只输出前面N条记录。
  2. LIMIT M,N:从第M条记录开始,输出N条记录。
  3. LIMIT N OFFSET M:MYSQL从5.0开始支持的语法,作用和第二条一样,从M开始输出N条记录。
第三种用法实际上是为了解决用户会混淆M,N究竟是从M开始的N条记录还是N开始的M条记录的问题。

2.5.1 显示前面5条记录

SELECT classno, city FROM stu_info LIMIT 5;

结果:

+---------+----------+
| classno | city     |
+---------+----------+
|       1 | changsha |
|       2 | shanghai |
|       2 | shenzhen |
|       3 | shenzhen |
|       4 | hunan    |
+---------+----------+

2.5.2 从第5条之后显示5条记录

SELECT classno, city FROM stu_info LIMIT 5, 5;

结果:

+---------+----------+
| classno | city     |
+---------+----------+
|       3 | wuhan    |
|       1 | changsha |
|       1 | changsha |
|       1 | fujian   |
+---------+----------+

当实际的记录数量小于剩余记录时,输出的结果并不会达到我们想要的行数。

使用SELECT classno, city from stu_info LIMIT 4 OFFSET 5的结果也和上面一样!

三、对结果排序

排序是查询是最常用的的功能之一,语法格式为ORDER BY col1, col2,表示根据col1col2排序。

MYSQL支持对单行和多行数据排序,也支持正序和倒序排序。默认情况是正序排序,逆序排序需要手动添加关键字DESC

3.1 对单列数据排序

输出学生的年龄、班级和名字,并针对年龄排序:

SELECT age, stu_name FROM stu_info ORDER BY age;

结果:

+-----+---------+-----------+
| age | classno | stu_name  |
+-----+---------+-----------+
|  19 |       2 | xiaoming  |
|  19 |       4 | xiaowang  |
|  20 |       3 | xiaozhou  |
|  20 |       1 | xiaoli    |
|  22 |       3 | xiaobai   |
|  22 |       1 | xiaozheng |
|  23 |       2 | xiaohua   |
|  23 |       1 | xiaopeng  |
|  24 |       1 | maqian    |
+-----+---------+-----------+

可以看到,age列都是从小到大排列,而classno还是处于无序的状态。

3.2 对多列数据排序

在上面的基础上,添加对班级排序逻辑。即当学生年龄一致的时候,根据所在的班级排序:

SELECT age, classno, stu_name FROM stu_info ORDER BY age, classno;

结果:

+-----+---------+-----------+
| age | classno | stu_name  |
+-----+---------+-----------+
|  19 |       2 | xiaoming  |
|  19 |       4 | xiaowang  |
|  20 |       1 | xiaoli    |
|  20 |       3 | xiaozhou  |
|  22 |       1 | xiaozheng |
|  22 |       3 | xiaobai   |
|  23 |       1 | xiaopeng  |
|  23 |       2 | xiaohua   |
|  24 |       1 | maqian    |
+-----+---------+-----------+

结果中,所有年龄相同的行,班级序号也是有序的。

3.3 逆序排序

逆序输出所有的学生名字:

SELECT stu_name FROM stu_info ORDER BY stu_name DESC;

结果:

+-----------+
| stu_name  |
+-----------+
| xiaozhou  |
| xiaozheng |
| xiaowang  |
| xiaopeng  |
| xiaoming  |
| xiaoli    |
| xiaohua   |
| xiaobai   |
| maqian    |
+-----------+

四、其他

4.1 使用完全限定的表名

查询时,可以明确查询的表名和列名,如:

SELECT stu_info.stu_name from stu_info;
注意:不可省略最后的表信息,不要认为列中限定了表名最后就不用再添加表名了。

效果等同于:

SELECT stu_name FROM stu_info;

这种用法一般适用于多表之间的联合查询,当两个表中的字段有重合时,需要明确指定表名来限定查询的是哪个表中的字段。

最后修改:2019 年 08 月 18 日
如果觉得我的文章对你有用,请随意赞赏