一、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
关键字可以限制输出的结果数量,语法格式为:
LIMIT N
:只输出前面N条记录。LIMIT M,N
:从第M条记录开始,输出N条记录。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
,表示根据col1
和col2
排序。
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;
这种用法一般适用于多表之间的联合查询,当两个表中的字段有重合时,需要明确指定表名来限定查询的是哪个表中的字段。
此处评论已关闭