【MySQL】DQL查询数据
DQL
(Data Query LANGUAGE :数据查询语言)
- 所有的查询操作都用它
select - 简单的查询,复杂的查询都能做
- ==数据库中最核心的语言,最重要的语句==
- 使用频率最高的语句
Select常用语法:
SELECT [ALL | DISTINCT]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
FROM table_name [as table_alias]
[left | right | inner join table_name2] #联合查询
[WHERE ...] -- 指定结果需满足的条件
[GROUP BY ...] -- 指定结果按照哪几个字段来分组
[HAVING] -- 过滤分组的记录必须满足的次要条件
[ORDER BY ...] -- 指定查询记录按一个或多个条件排序
[LIMIT {[offset,]row_count | row_countOFFSET offset}];
-- 指定查询的记录从哪条至哪条
==注意==:[] 代表可选,{}代表必选
Select 完整的语法:
SELECT
[ ALL | DISTINCT | DISTINCTROW ]
[ HIGH_PRIORITY ]
[ STRAIGHT_J0IN ]
[ SQL_SMALL_RESULT ] [ SQL_BIG_RESULT] [ SQL_BUFFER_RESULT]
[ SQL_CACHE | SQL_NO_CACHE] [ SQL_CALC_FOUND_ROWS]
select_expr [, select_expr...]
[ FRoM table_references
[ PARTITION partition_list]
[ WHERE where_condition ]
[ GROUP BY { col_name | expr | position}
[ ASC | DESC],...[ WITH ROLLUP]]
[ HAVING where_condition]
[ ORDER BY { col_name | expr | position}
[ ASC | DESC ],..]
[ LIMIT { [offset,] row_count | row_count OFFSET offset}]
[ PROCEDURE procedure_name(argument_1ist)]
[INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [,var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]
测试素材
https://gist.github.com/HuBoZhi/eee710db39b3f1745a3818fddc235f9b
或者https://gitcode.net/snippets/1690
指定查询字段
-- 查询全部学生 select 字段 from 表
select * from `student`;
-- 查询指定字段
select `StudentNo`,`StudentName` from `student`;
-- 别名,给结果起一个名字 AS 可以给字段起别名,也可以给表起别名
select `StudentNo` as 学号,`StudentName` as 学生姓名 from `student` AS s;
-- 函数 CONCAT(a,b)
select concat('姓名:',StudentName) as 新名字 from `student`;
语法:select 字段,... from 表
有的时候,列的名字不是那么的见名知意。所以我们起别名 AS: 字段名 as 别名 表名 as 别名
去重 distinct
作用:去除 Select 查询出来的结果中重复的数据,只显示一条
-- 查询一下哪些同学参加了考试 成绩
select * from result; -- 全部的成绩
select `StudentNo` from result; -- 查看有哪些同学参加了考试
select distinct `StudentNo` from result; -- 去除重复数据,去重
数据库的列 (表达式)
select version(); -- 查看系统版本(函数)
select 100*3-1 as 计算结果; -- 用来计算(表达式)
select @@auto_increment_increment -- 查询自增的步长
-- 学员考试成绩 +1 分查看
select `StudentNo`,`StudentResult` as 原来得分,`StudentResult`+1 as 提分后 from result;
where 条件子句
作用:检索数据中符合条件的值
搜索的条件由一个或者多个表达式组成!结果 布尔值。
逻辑运算符
| 运算符 | 语法 | 描述 |
|---|---|---|
| and && | a and b a&&b | 逻辑与 |
| or|| | a or b a|| b | 逻辑或 |
| Not ! | not a !a | 逻辑非 |
-- ===================== where ===========================
select `StudentNo`,`StudentName` from `student`;
-- 查询考试成绩在 95~100 分之间
select `StudentNo`,`StudentResult`
from `result`
where `StudentResult`>=95 and `StudentResult`<=100;
-- and &&
select `StudentNo`,`StudentResult`
from `result`
where `StudentResult`>=95 && `StudentResult`<=100;
-- 模糊查询(区间)
select `StudentNo`,`StudentResult`
from `result`
where StudentResult between 95 and 100;
-- 除了1000学号以外的同学的成绩
-- !=
select `StudentNo`,`StudentResult`
from `result`
where `StudentNo`!=1000;
-- <>
select `StudentNo`,`StudentResult`
from `result`
where `StudentNo`<>1000;
-- not
select `StudentNo`,`StudentResult`
from `result`
where not `StudentNo`=1000;
模糊查询:比较运算符
| 运算符 | 语法 | 描述 |
|---|---|---|
| IS NULL | a is null | 如果操作符为NULL,结果为真 |
| IS NOT NULL | a is not null | 如果操作符不为NULL,结果为真 |
| BETWEEN | a between b and c | 若a在b和c之间,结果为真 |
| like | a like b | SQL匹配,如果a匹配b,则结果为真 |
| in | a in (a1,a2,a3) | 假设a在a1,a2,…,其中的某一个值中,结果为真 |
-- ================= 模糊查询 ==================
-- 查询姓刘的同学
select `StudentNo`,`StudentName`
from `student`
where `StudentName` like '刘%';
-- 查询姓刘的同学,并且后面只有一个字的
select `StudentNo`,`StudentName`
from `student`
where `StudentName` like '刘_';
-- 查询姓刘的同学,后面有两个字的
select `StudentNo`,`StudentName`
from `student`
where `StudentName` like '刘__';
-- 查询名字中间有嘉字的
select `StudentNo`,`StudentName`
from `student`
where `StudentName` like '%嘉%';
-- ======================= in =========================
-- 查询 1001,1002,1003 号学员
select `StudentNo`,`StudentName`
from `student`
where `StudentNo` in (1001,1002,1003);
-- 查询在安徽的学生
select `StudentNo`,`StudentName` ,`Address`
from `student`
where `Address` in ('安徽','河南洛阳');
-- ================ null not null ================
-- 查询性别为空的学生
select `StudentNo`,`StudentName` ,`sex`
from `student`
where `sex` is null;
-- 查询有出生日期的学生, 不为空
select `StudentNo`,`StudentName` ,`BornDate`
from `student`
where `BornDate` is not null;
-- 查询没有出生日期的学生
select `StudentNo`,`StudentName` ,`BornDate`
from `student`
where `BornDate` is null;
-- 查询学员所属的年级
select StudentNo,`StudentName`,`GradeName`
from `student` as s
inner join `grade` as g
on s.GradeId = g.GradeID;
-- 查询科目所属的年级
select SubjectName,`GradeName`
from `subject` as `sub`
inner join `grade` as g
on sub.GradeID = g.GradeID;
-- 查询参加了 数据库结构-1 考试的同学的信息:学号,学生姓名,分数
select s.StudentNo,StudentName,StudentResult
from `student` as s
inner join `result` as r
on s.StudentNo = r.StudentNo
inner join `subject` as `sub`
on r.SubjectNo = sub.SubjectNo
where SubjectName='数据库结构-1';
连接查询


/* 思路
1. 分析需求,分析查询的字段来自哪些表,(连接查询)
2. 确定使用那种连接:7种
确定交叉点,这两个表中那个字段是相同的
判断的条件:学生表中 StudentNo = 成绩表中 StudentNo
*/
-- join on 连接查询
-- where 等值查询
select s.StudentNo,StudentName,SubjectNo,StudentResult
from student as s inner join result as r
on s.StudentNo = r.StudentNo;
-- Right Join
-- as 可以省略
select s.StudentNo,StudentName,SubjectNo,StudentResult
from student s right join result r
on s.StudentNo = r.StudentNo;
-- Left Join
select s.StudentNo,StudentName,SubjectNo,StudentResult
from student as s left join result as r
on s.StudentNo = r.StudentNo;
| 操作 | 描述 |
|---|---|
Inner Join |
如果表中至少一个匹配,就返回该行 |
Left Join |
会从做左表中返回所有的值,即使右表中没有匹配 |
Right Join |
会从做右表中返回所有的值,即使左表中没有匹配 |
-- 查询缺考的同学
select s.StudentNo,StudentName,SubjectNo,StudentResult
from student as s left join result as r
on s.StudentNo = r.StudentNo
where StudentResult is null;
-- 思考题(查询参加考试的同学的信息:学号,学生姓名,科目名,分数)
/* 思路
1. 分析需求,分析查询的字段来自哪些表,(连接查询)
2. 确定使用那种连接:7种
确定交叉点,这两个表中那个字段是相同的
判断的条件:学生表中 StudentNo = 成绩表中 StudentNo
*/
select s.StudentNo,StudentName,SubjectName,StudentResult
from student as s
right join result as r
on s.StudentNo = r.StudentNo
left join `subject` as sub
on sub.SubjectNo = r.SubjectNo;
-- 我要查询哪些数据 select...
-- 从那几个表中查 from 表 XXX join 连接的表 on 交叉条件
-- 假设存在一种多张表查询,慢慢来,先查询两张表
-- from a left join b
-- from a right join b
自连接
自己的表和自己的表连接,核心:一张表拆为两张一样的表即可
父表:
| categoryid | categoryName |
|---|---|
| 2 | 信息技术 |
| 3 | 软件开发 |
| 5 | 美术设计 |
子表:
| pid | categoryid | categoryName |
|---|---|---|
| 3 | 4 | 数据库 |
| 2 | 8 | 办公信息 |
| 3 | 6 | web开发 |
| 5 | 7 | 美术设计 |
操作:查询父类对应的子类关系
| 父类 | 子类 |
|---|---|
| 信息技术 | 办公信息 |
| 软件开发 | 数据库 |
| 软件开发 | web开发 |
| 美术设计 | PS技术 |
分页和排序
排序
-- 排序:升序:ASC 降序:DESC
-- ORDER BY [通过哪个字段排] [怎么排:升序/降序]
-- 查询结果的根据 成绩降序 排序
select s.StudentNo,StudentName,SubjectName,StudentResult
from student as s
inner join result as r
on s.StudentNo = r.StudentNo
inner join `subject` as sub
on sub.SubjectNo = r.SubjectNo
where SubjectName = 'JAVA第一学年'
order by StudentResult DESC;
分页
-- 100万条数据
-- 为什么要分页
-- 缓解数据库压力,给人更好的体验,瀑布流和分页不同
--
-- 分页 每页只显示五条数据
-- 语法: limit 起始值,页面大小
-- 网页应用:当前,总的页数,页面大小
-- LIMIT 0,5 1~5
-- LIMIT 1,5 2~6
-- LIMIT 6,5
select s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
from student as s
inner join result as r
on s.StudentNo = r.StudentNo
inner join `subject` as sub
on r.SubjectNo = sub.SubjectNo
where SubjectName='数据库结构-1'
order by StudentResult ASC
limit 1,5;
-- 第一页 limit 0,5 (1-1)*5
-- 第一页 limit 6,5 (2-1)*5
-- 第一页 limit 10,5 (3-1)*5
-- 第N页 limit 0,5 (n-1)*pageSize,pageSize
-- 【pageSize】:页面大小
-- 【(n-1)*pageSize】:起始值
-- 【n】:当前页
-- 【数据总数/页面大小】:总页数
语法:limit 查询的起始下标, pageSize
子查询
where (这个值是计算出来的)
本质:在 where 语句中嵌套一个子查询语句
-- 思考:
-- 查询JAVA第一学年 课程成绩排名前十的学生,并且分数要大于八十的学生信息(学号,姓名,课程名称,分数)
select s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
from `student` as s
inner join `result` as r
on s.StudentNo = r.StudentNo
inner join `subject` as sub
on r.SubjectNo = sub.SubjectNo
where SubjectName='JAVA第一学年' and StudentResult>=80
order by StudentResult ASC;
-- 查询 数据库结构-1 的所有考试结果(学号,科目编号,成绩),降序排列
-- 方式一:使用连接查询
select StudentNo,sub.SubjectNo,StudentResult
from`result` as r
inner join `subject` as sub
on sub.SubjectNo = r.SubjectNo
where SubjectName='数据库结构-1'
order by StudentResult DESC;
-- 方式二:使用子查询(由里及外)
select StudentNo,SubjectNo,StudentResult
from `result`
where SubjectNo in (
select `SubjectNo`
from `subject`
where SubjectName='数据库结构-1'
)
order by StudentResult DESC;
-- 查询课程为 高等数学-2 且分数不小于80的同学的学号和姓名
select s.StudentNo,StudentName
from `student` as s
inner join `result` as r
on s.StudentNo = r.StudentNo
inner join `subject` as sub
on r.SubjectNo = sub.SubjectNo
where `StudentResult`>=80 and `SubjectName`='高等数学-2';
-- 分数不小于80的同学的学号和姓名
select `StudentNo`,`StudentName`
from `student`
where `StudentNo` in (
select `StudentNo`
from `result`
where `StudentResult`>=80
);
-- 在这个基础上增加一个科目,高等数学-2
-- 查询 高等数学-2 的编号
select `SubjectNo`
from `subject`
where `SubjectName`='高等数学-2';
-- 综上改造
select `StudentNo`,`StudentName` from `student`
where `StudentNo` in (
select `StudentNo` from `result` where `StudentResult`>=80 and `SubjectNo`in (
select `SubjectNo` from `subject` where `SubjectName`='高等数学-2'
)
);
-- 练习: 查询C语言-1前五名同学的成绩的信息(学号,姓名,成绩)
-- 使用子查询
select s.`StudentNo`,`StudentName`,`StudentResult`
from `student` as s
inner join `result` as r
where s.`StudentNo` in (
select `StudentNo` from `result` where `SubjectNo` in (
select `SubjectNo` from `subject` where `SubjectName`='C语言-1'
)
order by `StudentResult` ASC
)
limit 5;
分组和过滤
-- 查询不同课程的平均分,最高分,最低分,平均分大于80
-- 核心:(根据不同的课程分组)
select SubjectName,AVG(`StudentResult`) as 平均分,MAX(`StudentResult`) as 最大值,MIN(`StudentResult`) as 最小值
from `result` as r
inner join `subject` sub
on r.SubjectNo = sub.SubjectNo
GROUP BY r.`SubjectNo` -- 通过什么字段来分组
having 平均分>=80;
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员小航
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果