SELECT语句用来查询数据。查询数据是指从数据库中根据需求,使用不同的查询方式来获取不同的数据,是使用频率最高、最重要的操作。
SELECT语法格式:
SELECT{* | <字段列名>} FROM <表 1>, <表 2>…
[WHERE <表达式>
[GROUP BY <group by definition>
[HAVING <expression> [{<operator> <expression>}…]]
[ORDER BY <order by definition>]
[LIMIT[<offset>,] <row count>]
* 其中,各条子句的含义如下:
1){*|<字段列名>}包含星号通配符的字段列表,表示所要查询字段的名称。
2)<表 1>,<表 2>…,表 1 和表 2 表示查询数据的来源,可以是单个或多个。
3)WHERE <表达式>是可选项,如果选择该项,将限定查询数据必须满足该查询条件。
4)GROUP BY< 字段 >,该子句告诉 MySQL 如何显示查询出来的数据,并按照指定的字段分组。
5)[ORDER BY< 字段 >],该子句告诉 MySQL 按什么样的顺序显示查询出来的数据,可以进行的排序有升序(ASC)和降序(DESC),默认情况下是升序。
6)[LIMIT[<offset>,]<row count>],该子句告诉 MySQL 每次显示查询出来的数据条数。
查询表中所有字段
查询所有字段是指查询表中所有字段的数据。MySQL 提供了以下 2 种方式查询表中的所有字段。
1)使用“*”通配符查询所有字段
使用“*”查找表中所有字段的数据,语法格式:SELECT * FROM 表名;
使用“*”查询时,只能按照数据表中字段的顺序进行排列,不能改变字段的排列顺序。
使用“*”通配符时,将返回所有列,数据列按照创建表时的顺序显示。
MySQL [mysql_chuid]> select * from students; # 查询表students中所有字段的数据
+----+-----------+-------+--------+--------+
| id | name_list | sex | weight | height |
+----+-----------+-------+--------+--------+
| 1 | chd | man | 130 | 171 |
| 2 | wang | woman | 105 | 165 |
| 5 | anivd | man | 130 | 171 |
| 7 | zhang | woman | 98 | 162 |
| 8 | chen | man | 130 | 170 |
+----+-----------+-------+--------+--------+
5 rows in set (0.02 sec)
一般情况下,除非需要使用表中所有的字段数据,否则最好不要使用通配符“*”。虽然使用通配符可以节省输入查询语句的时间,但是获取不需要的列数据通常会降低查询和所使用的应用程序的效率。使用“*”的优势是,当不知道所需列的名称时,可以通过“*”获取它们。
2)列出表的所有字段
SELECT关键字后面的字段名为需要查找的字段,因此可以将表中所有字段的名称跟在SELECT关键字后面。如果忘记了字段名称,可以使用DESC命令查看表的结构。有时由于表的字段比较多,不一定能记得所有字段的名称,因此该方法很不方便,不建议使用。
MySQL [mysql_chuid]> SELECT id,name,sex FROM students_3; # 查询表students_3中的所有数据
+----+-------+------+
| id | name | sex |
+----+-------+------+
| 1 | chuid | 26 |
+----+-------+------+
1 row in set (0.00 sec)
这种查询方式比较灵活,如果需要改变字段显示的顺序,只需调整SELECT关键字后面的字段列表顺序即可
查询表中指定的字段
查询表中的某一个字段的语法格式:SELECT < 列名 > FROM < 表名 >;
MySQL [mysql_chuid]> SELECT name_list FROM students_2; # 查询students_2中name_list字段下的所有数据
+-----------+
| name_list |
+-----------+
| chd |
+-----------+
1 row in set (0.00 sec)
使用SELECT声明可以获取多个字段下的数据,只需要在关键字SELECT后面指定要查找的字段名称,不同字段名称之间用逗号“,”分隔开,最后一个字段后面不需要加逗号。
语法格式:SELECT <字段名1>,<字段名2>,…,<字段名n> FROM <表名>;
MySQL [mysql_chuid]> SELECT id,name_list,weight FROM students;
+----+-----------+--------+
| id | name_list | weight |
+----+-----------+--------+
| 1 | chd | 130 |
| 2 | wang | 105 |
| 5 | anivd | 130 |
| 7 | zhang | 98 |
| 8 | chen | 130 |
+----+-----------+--------+
5 rows in set (0.00 sec)
去重
在MySQL中使用SELECT语句执行简单的数据查询时,返回的是所有匹配的记录。如果表中的某些字段没有唯一性约束,那么这些字段就可能存在重复值。为了实现查询不重复的数据,MySQL提供了DISTINCT关键字。
DISTINCT关键字的主要作用就是对数据表中一个或多个字段重复的数据进行过滤,只返回其中的一条数据给用户。
DISTINCT关键字的语法格式:SELECT DISTINCT <字段名> FROM <表名>;
其中,“字段名”为需要消除重复记录的字段名称,多个字段时用逗号隔开。
* 使用DISTINCT关键字时需要注意以下几点:
1)DISTINCT 关键字只能在SELECT语句中使用。
2)在对一个或多个字段去重时,DISTINCT关键字必须在所有字段的最前面。
3)如果DISTINCT关键字后有多个字段,则会对多个字段进行组合去重,也就是说,只有多个字段组合起来完全是一样的情况下才会被去重。
MySQL [mysql_chuid]> SELECT id,name_list,weight FROM students;
+----+-----------+--------+
| id | name_list | weight |
+----+-----------+--------+
| 1 | chd | 130 |
| 2 | wang | 105 |
| 5 | anivd | 130 |
| 7 | zhang | 98 |
| 8 | chen | 130 |
+----+-----------+--------+
5 rows in set (0.00 sec)
MySQL [mysql_chuid]> SELECT DISTINCT weight FROM students; # 查询表students中不重复数据
+--------+
| weight |
+--------+
| 130 |
| 105 |
| 98 |
+--------+
3 rows in set (0.02 sec)
MySQL [mysql_chuid]> SELECT DISTINCT sex,weight FROM students; # 对students表的sex和weight字段进行去重
+-------+--------+
| sex | weight |
+-------+--------+
| man | 130 |
| woman | 105 |
| woman | 98 |
+-------+--------+
3 rows in set (0.00 sec)
MySQL [mysql_chuid]> SELECT DISTINCT * FROM students; # 对students表中的所有字段进行去重
+----+-----------+-------+--------+--------+
| id | name_list | sex | weight | height |
+----+-----------+-------+--------+--------+
| 1 | chd | man | 130 | 171 |
| 2 | wang | woman | 105 | 165 |
| 5 | anivd | man | 130 | 171 |
| 7 | zhang | woman | 98 | 162 |
| 8 | chen | man | 130 | 170 |
+----+-----------+-------+--------+--------+
5 rows in set (0.00 sec)
因为DISTINCT只能返回它的目标字段,而无法返回其它字段,所以在实际情况中,我们经常使用DISTINCT关键字来返回不重复字段的条数。
MySQL [mysql_chuid]> SELECT COUNT(DISTINCT sex,weight) FROM students; # 查询表students中对sex和weight去重之后有3条记录
+----------------------------+
| COUNT(DISTINCT sex,weight) |
+----------------------------+
| 3 |
+----------------------------+
1 row in set (0.00 sec)
设置别名
当表名很长或者执行一些特殊查询的时候,为了方便操作,可以为表指定一个别名,用这个别名代替表原来的名称。
为表指定别名的基本语法格式: <表名> [AS] <别名>
* 表的别名不能与该数据库的其它表同名。字段的别名不能与该表的其它字段同名!
* 其中各子句的含义如下:
1)<表名>:数据库中存储的数据表的名称。
2)<别名>:查询时指定的表的新名称。
3)AS关键字可以省略,省略后需要将表名和别名用空格隔开。
MySQL [mysql_chuid]> SELECT stu.id,stu.name,stu.sex FROM students_3 AS stu; # 为表students_3指定别名stu
+----+-------+------+
| id | name | sex |
+----+-------+------+
| 1 | chuid | 26 |
+----+-------+------+
1 row in set (0.00 sec)
为字段指定别名
在使用SELECT语句查询数据时,MySQL会显示每个SELECT后面指定输出的字段。有时为了显示结果更加直观,我们可以为字段指定一个别名。
为字段指定别名的基本语法格式:<字段名> [AS] <别名>
* 其中,各子句的语法含义如下:
1)<字段名>:为数据表中字段定义的名称。
2)<字段别名>:字段新的名称。
3)AS关键字可以省略,省略后需要将字段名和别名用空格隔开。
MySQL [mysql_chuid]> SELECT name AS stu_name,sex AS stu_sex FROM students_3; # 查询students_3表,为name和sex指定别名
+----------+---------+
| stu_name | stu_sex |
+----------+---------+
| chuid | 26 |
+----------+---------+
1 row in set (0.00 sec)
表别名只在执行查询时使用,并不在返回结果中显示。而字段定义别名之后,会返回给客户端显示,显示的字段为字段的别名。
限制查询结果的条数
当数据表中有上万条数据时,一次性查询出表中的全部数据会降低数据返回的速度,同时给数据库服务器造成很大的压力。这时就可以用LIMIT关键字来限制查询结果返回的条数。
LIMIT是MySQL中的一个特殊关键字,用于指定查询结果从哪条记录开始显示,一共显示多少条记录。
* LIMIT关键字有3种使用方式,即指定初始位置、不指定初始位置以及与OFFSET组合使用。
指定初始位置
LIMIT关键字可以指定查询结果从哪条记录开始显示,显示多少条记录。
LIMIT指定初始位置的基本语法格式:LIMIT初始位置,记录数
其中,“初始位置”表示从哪条记录开始显示;“记录数”表示显示记录的条数。第一条记录的位置是0,第二条记录的位置是1。后面的记录依次类推。
* LIMIT后的两个参数必须都是正整数。
# 在students表中,使用LIMIT子句返回从第4条记录开始的行数为5的记录
MySQL [mysql_chuid]> SELECT * FROM students LIMIT 3,5;
+----+-----------+-------+--------+--------+
| id | name_list | sex | weight | height |
+----+-----------+-------+--------+--------+
| 4 | liu | woman | 132 | 169 |
| 5 | anivd | man | 130 | 171 |
| 6 | luo | woman | 118 | 162 |
| 7 | zhang | woman | 98 | 162 |
| 8 | chen | man | 130 | 170 |
+----+-----------+-------+--------+--------+
5 rows in set (0.00 sec)
# 在students表中,使用LIMIT子句返回从第4条记录开始的行数为3的记录
MySQL [mysql_chuid]> SELECT * FROM students LIMIT 3,3;
+----+-----------+-------+--------+--------+
| id | name_list | sex | weight | height |
+----+-----------+-------+--------+--------+
| 4 | liu | woman | 132 | 169 |
| 5 | anivd | man | 130 | 171 |
| 6 | luo | woman | 118 | 162 |
+----+-----------+-------+--------+--------+
3 rows in set (0.00 sec)
不指定初始位置
LIMIT关键字不指定初始位置时,记录从第一条记录开始显示。显示记录的条数由LIMIT关键字指定。
LIMIT不指定初始位置的基本语法格式:LIMIT 记录数
其中,“记录数”表示显示记录的条数。如果“记录数”的值小于查询结果的总数,则会从第一条记录开始,显示指定条数的记录。如果“记录数”的值大于查询结果的总数,则会直接显示查询出来的所有记录。
MySQL [mysql_chuid]> SELECT * FROM students LIMIT 5; # 查询表students中前5条记录
+----+-----------+-------+--------+--------+
| id | name_list | sex | weight | height |
+----+-----------+-------+--------+--------+
| 1 | chd | man | 130 | 171 |
| 2 | wang | woman | 105 | 165 |
| 3 | li | man | 132 | 169 |
| 4 | liu | woman | 132 | 169 |
| 5 | anivd | man | 130 | 171 |
+----+-----------+-------+--------+--------+
5 rows in set (0.00 sec)
带一个参数的LIMIT指定从查询结果的首行开始,唯一的参数表示返回的行数,即“LIMIT n”与“LIMIT 0,n”返回结果相同。带两个参数的LIMIT可返回从任何位置开始指定行数的数据。
LIMIT和OFFSET组合使用
LIMIT 可以和 OFFSET 组合使用,语法格式:LIMIT 记录数 OFFSET 初始位置
参数和LIMIT语法中参数含义相同,“初始位置”指定从哪条记录开始显示;“记录数”表示显示记录的条数。
# 使用LIMIT OFFSET返回从第6条记录开始的行数为3的记录
MySQL [mysql_chuid]> SELECT * FROM students LIMIT 3 OFFSET 5;
+----+-----------+-------+--------+--------+
| id | name_list | sex | weight | height |
+----+-----------+-------+--------+--------+
| 6 | luo | woman | 118 | 162 |
| 7 | zhang | woman | 98 | 162 |
| 8 | chen | man | 130 | 170 |
+----+-----------+-------+--------+--------+
3 rows in set (0.00 sec)
对查询结果排序
通过条件查询语句可以查询到符合用户需求的数据,但是查询到的数据一般都是按照数据最初被添加到表中的顺序来显示。为了使查询结果的顺序满足用户的要求,MySQL提供了ORDER BY关键字来对查询结果进行排序。
ORDER BY关键字主要用来将查询结果中的数据按照一定的顺序进行排序。
语法格式:ORDER BY <字段名> [ASC|DESC]
* 语法说明:
1)字段名:表示需要排序的字段名称,多个字段时用逗号隔开。
2)ASC|DESC:ASC表示字段按升序排序;DESC表示字段按降序排序。其中ASC为默认值。
* 使用ORDER BY关键字应该注意以下几个方面:
1)ORDER BY关键字后可以跟子查询(关于子查询后面教程会详细讲解,这里了解即可)。
2)当排序的字段中存在空值时,ORDER BY会将该空值作为最小值来对待。
3)ORDER BY指定多个字段进行排序时,MySQL会按照字段的顺序从左到右依次进行排序。
单字段排序
* 对多个字段进行排序时,排序的第一个字段必须有相同的值,才会对第二个字段进行排序。如果第一个字段数据中所有的值都是唯一的,MySQL将不再对第二个字段进行排序。
# 查询表students中的name_list和sex字段,先按sex排序,再按name_list排序
MySQL [mysql_chuid]> SELECT name_list,sex FROM students ORDER BY sex,name_list;
+-----------+-------+
| name_list | sex |
+-----------+-------+
| anivd | man |
| chd | man |
| chen | man |
| li | man |
| liu | woman |
| luo | woman |
| wang | woman |
| zhang | woman |
+-----------+-------+
8 rows in set (0.12 sec)
* 默认情况下,查询数据按字母升序进行排序(A~Z),但数据的排序并不仅限于此,还可以使用ORDER BY中的DESC对查询结果进行降序排序(Z~A)
# 查询表students,先按height降序排序,再按name_list升序排序
MySQL [mysql_chuid]> SELECT name_list,height FROM students ORDER BY height DESC,name_list ASC;
+-----------+--------+
| name_list | height |
+-----------+--------+
| anivd | 171 |
| chd | 171 |
| chen | 170 |
| li | 169 |
| liu | 169 |
| wang | 165 |
| luo | 162 |
| zhang | 162 |
+-----------+--------+
8 rows in set (0.00 sec)
* DESC关键字只对前面的列进行降序排列,在这里只对height字段进行降序。因此,height按降序排序,而name_list仍按升序排序。如果想在多个列上进行降序排序,必须对每个列指定DESC关键字。