简述
在sql中,很多时候我们的操作都是在查询数据,本章详解了sql中不同查询的用法和功能。
查询数据库中的数据都是用select语句,搭配不同的关键字实现不同的效果。
基本查询
如果要查询数据库表的数据,SQL语句格式如下:
SELECT * FROM <表名>
返回的结果是该表所有行的数据
条件查询
在基本查询的基础上,我们希望给返回的结果加上一点条件
例如我们想查询分数在80分以上的学生记录,我们可以使用where关键字来设定查询的条件。
SELECT * FROM students WHERE score >= 80;
其中score是表的列名,该列存储了学生的成绩。
投影查询
如果我们只希望返回某些列的数据,而不是所有列的数据,我们可以用
SELECT 列1, 列2, 列3 FROM ...
这会让结果集仅包含指定列,这种操作称为投影操作。
SELECT id, score, name FROM students;
查询结果的排序
查询结果集通常是按照id
排序的,也就是根据主键排序,这也是大部分数据库的做法。
如果我们想根据其他条件排序,可以使用order by语句。
ORDER BY 排序列表 [ASC|DESC];
其中asc代表的是升序,desc代表的是降序,如果不写,默认是升序
例如将成绩由低到高排序
SELECT id, name, gender, score FROM students ORDER BY score;
例如将成绩由高到低排序
SELECT id, name, gender, score FROM students ORDER BY score DESC;
分页查询
用SELECT查询时,如果结果集数据量很大,比如几万行数据,放在一个页面显示的话数据量太大,不如分页显示,每次显示100条。要实现分页功能,实际上就是从结果集中显示第1~100条记录作为第1页,显示第101~200条记录作为第2页,以此类推。
LIMIT <N-M> OFFSET <M>
其中首先是limit,limit后面如果跟着两个参数的时候,第一个数表示要跳过的数量,后一位表示要取的数量
select* from article LIMIT 1,3
这样则表示跳过一条数据,然后取3条数据
当limit跟着一个参数的时候,代表要取的数据的数量
select* from article LIMIT 3
这样代表直接取前3条数据
当 limit和offset组合使用的时候,limit后面只能有一个参数,表示要取的的数量,offset表示要跳过的数量 。
select * from article LIMIT 3 OFFSET 1
这样代表表示跳过1条数据,取3条数据
多表查询
我们在使用select关键字对数据库进行查询的时候,可以用从多张表同时查询数据。
SELECT * FROM students, classes;
这样查询出来的结果集,它是students
表和classes
表的笛卡尔乘积,即students
表的每一行与classes
表的每一行都两两拼在一起返回。结果集的列数是students
表和classes
表的列数之和,行数是students
表和classes
表的行数之积。
连接查询
连接查询是另一种类型的多表查询。连接查询对多个表进行JOIN运算,简单地说,就是先确定一个主表作为结果集,然后,把其他表的行有选择性地“连接”在主表结果集上。
连接可以分为内连接、左外连接、右外连接和全外连接
需要注意的是表是可以和自己连接的,这是就要给表取别名,达到区分两张表的目的
使用join的同时需要使用on关键字指定你想要连接的字段名,也可以使用USING(字段名),这里的字段名就是两张表相同的字段名
下面我们以student表和class表举例
内连接
内连接就是选出两张表中都存在的记录
SELECT * FROM student INNER JOIN class on student.classid = class.classid
左外连接
左外连接可以理解为保留左表中的全部数据,将右表中有交集的数据拼接在右方
SELECT * FROM student LEFT OUTER JOIN class on student.classid = class.classid
注意如果右表没有交集数据,则拼接null的数据,如上图的第5条数据
右外连接
右外连接可以理解为保留右表中的全部数据,将左表中有交集的数据拼接在右方
SELECT * FROM student RIGHT OUTER JOIN class on student.classid = class.classid
全外连接
全外连接就是选出左右两张表都存在的数据,本质上就是将左外连接和右外连接拼起来
SELECT * FROM student FULL OUTER JOIN class on student.classid = class.classid
需要注意的是有的数据库不支持全外连接,但是我们基于全外连接的本质
可以手动地将左外和右外拼接起来,达到我们要的全外连接效果,使用的是UNION关键字
SELECT * FROM student LEFT OUTER JOIN class on student.classid = class.classid UNION SELECT * FROM student RIGHT OUTER JOIN class on student.classid = class.classid
注意只写join默认的是内连接,union默认去重,如果要查出重复数据可以使用union all关键字
聚合查询
有时候我们需要汇总数据而不是将他们检索出来,为此sql提供了专门的函数。
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值() |
SUM() | 返回某列值之和 |
举例:
select AVG(age) from student;
从Mysql5版本开始,我们可以在聚合函数内使用DISTINCT关键字,求出不同列数据的聚合值,例如:
select AVG(DISTINCT age) from student;
但DISTINCT不能用于COUNT(*)
聚合函数不能和where关键字一起使用,如果我们想对聚合后的函数进行筛选,则要使用having关键字
简单来说就是where是过滤行用的,having是过滤分组用的
References
https://www.liaoxuefeng.com/