目录
4、DQL查询数据(最重点)
4.1、DQL
(Data Query Language:数据查询语言)
- 所用查询操作都用它 Select
- 简单的查询,复杂的查询它都能做
- 数据库中最核心的语言,最重要的语言
- 使用频率最高的语言
4.2、指定字段查询
-- 查询全部的学生 SELECT 字段 FROM 表名
SELECT * FROM student1 -- * 号代表全部
-- 查询指定字段
SELECT `name`,`pwd` FROM `student1`
-- 别名 给结果起一个名字 AS 可以给字段区别名,也可以给表起别名
SELECT `name` AS 学号 ,`pwd` AS 密码 FROM `student1` AS s
-- 函数 Concat(a,b)
SELECT CONCAT('姓名:',name) AS 新名字 FROM `student1`
语法:SELECT 字段 FROM 表
有些时候,列明在不是那么见名知意。我们可以通过 AS 来起别名
字段名 AS 别名
- 去重
去重 distinct
作用:去除SELECT查询出来的结果在重复的数据,重复数据只显示一条
-- 查询一下有哪些同学参加了考试
SELECT * FROM result -- 查询全部的考试成绩
SELECT `StudentNo` FROM result -- 查询有哪些同学参加了考试 ,有成绩即参加了考试
SELECT DISTINCT `StudentNo` FROM result -- 发现重复数据,去重
下面让我们来玩一玩SELECT的一些用法
数据库的列(表达式)
SELECT VERSION() -- 查询MySQL系统版本
SELECT 100*3-1 AS 计算结果 -- 用来计算(表达式)
SELECT @@auto_increment_increment -- 查询自增的步长 (变量)
-- 将学员的考试成绩+1后查看
SELECT `StudentNo`,`StudentResult` + 1 AS 提分后 FROM `result`
数据库中的表达式:文本值,列,NULL,函数,计算表达式,系统变量……
SELECT 表达式 from 表
4.3、where条件子句
作用:检索数据中符合条件的值
搜索的条件由一个或多个表达式组成
逻辑运算符
运输符 | 语法 | 描述 |
and && | a and b a && b | 逻辑与,两个都为真,结果为真 |
or || | a or b a || b | 逻辑或,其中一个为真,结果为真 |
NOt ! | Not a ! a | 逻辑非,真为假,假为真 |
尽量使用英文字母
-- 查询考试成绩
SELECT `StudentNo` , `StudentResult` FROM result ;
-- 查询考试成绩在90~95之间
SELECT `StudentNo` , `StudentResult` FROM result WHERE `StudentResult`>=90 AND `StudentResult` <=95;-- 方式一
SELECT `StudentNo` , `StudentResult` FROM result WHERE `StudentResult`>=90 && `StudentResult` <=95;-- 方式二
-- 模糊查询(区间)
SELECT `StudentNo` , `StudentResult` FROM result WHERE `StudentResult` BETWEEN 90 AND 95;
-- 查询除了55号学生之外所有同学的成绩
SELECT `StudentNo` , `StudentResult` FROM result WHERE `StudentNo`!=55;-- 方式一
SELECT `StudentNo` , `StudentResult` FROM result WHERE NOT `StudentNo`=55;-- 方式二
模糊查询
运算符 | 语法 | 描述 |
IS NULL | a IS NULL | 如果操作符为NULL,结果为真 |
IS NOT NULL | a IS NOT NULL | 如果操作符为NULL,结果为假 |
BETWEEN | a BETWEENb AND c | 若a在b和c之间,则结果为真 |
LIKE | a LIKE b | SQL匹配,如果a匹配b,则结果为真 |
IN | a IN(a1,a2,a3……) | 假设a在a1,或者a2……其中的某一个值中,结果为真 |
-- ===============LIKE(模糊查询)============
-- 查询姓王的同学
-- like结合 %(代表0到任意个字符) ——(代表一个字符)
SELECT `name` ,`pwd` FROM `student1` WHERE `name` LIKE '王%'
-- 查询姓王的同学,王字后只有一个字
SELECT `name` ,`pwd` FROM `student1` WHERE `name` LIKE '王_'
-- 查询姓王的同学,王字后只有两个字
SELECT `name` ,`pwd` FROM `student1` WHERE `name` LIKE '王__'
-- =============IN(具体的一个或多个值)====================
-- 查询 1,2,3号学员
SELECT `id` ,`name` FROM `student1` WHERE `id` IN(1,2,3)
-- 查询在芜湖的学生
SELECT `id`,`name` FROM `student1` WHERE `address` IN('芜湖')
-- ===============NULL 和 NOT NULL ===============
-- 查询填写了地址的同学
SELECT `id`,`name` FROM `student1` WHERE `address` IS NOT NULL
-- 查询地址为空的同学
SELECT `id`,`name` FROM `student1` WHERE `address` IS NULL OR address = ''
-- 查询没有填写地址的同学
SELECT `id`,`name` FROM `student1` WHERE `address` IS NULL
4.4、联表查询
-- ======================联表查询==========================
-- INNER JOIN
-- RIGHT JOIN
-- LEFT JOIN
-- 查询参加了考试的同学的(学号,姓名,科目编号,分数)
/*思路
1.分析需求,分析查询的字段来自哪些表,如果超过一个,就需要使用,连接查询
2.确定使用哪种连接查询?一共有7种
确定交叉点(需要连接查询的表中,哪个数据是相同的)
判断的条件: 学生表中的id = 成绩表中的id
*/
-- INNER JOIN
SELECT `s.id`,`name`,`SubjectNo`,`StudentResult`
FROM `student1` AS s
INNER JOIN result AS r
WHERE s.id = r.id
-- RIGHT JOIN
SELECT `s.id`,`name`,`SubjectNo`,`StudentResult`
FROM `student1` AS s
RIGHT JOIN result AS r
WHERE s.id = r.id
-- LEFT JOIN
SELECT `s.id`,`name`,`SubjectNo`,`StudentResult`
FROM `student1` AS s
LEFT JOIN result AS r
WHERE s.id = r.id -- 或者将WHERE换成ON,是一样的效果
操作 | 描述 |
INNER JOIN | 如果表中至少有一个匹配,就返回行 |
RIGHT JOIN | 会从右表中返回所有的值,及时左表中没有匹配 |
LEFT JOIN | 会从左表中返回所有的值,及时右表中没有匹配 |
join (连接的表)on (判断的条件) 连接查询
where 等值查询
-- 查询缺考的同学
SELECT s.`id`,`name`,`SubjectNo`,`StudentResult`
FROM `student1` AS s
LEFT JOIN result AS r
ON s.`id` = r.`id`
WHERE `StudentResult` IS NULL
-- 思考题(查询参加考试的同学的信息:学号,学生姓名,科目名,分数)
/*思路
1.分析需求,分析查询的字段来自哪些表,如果超过一个,就需要使用,连接查询
本次查询需要查询三张表 student result subject
2.确定使用哪种连接查询?一共有7种
确定交叉点(需要连接查询的表中,哪个数据是相同的)
判断的条件: 学生表中的id = 成绩表中的id
*/
SELECT s.`id`,`name`,subjectName`,studentResult`
FROM `student` AS s
RIGHT JOIN `result` AS r
ON s.`id` = r.`id`
INNER JOIN `subject` AS sub
ON r.`subjectNo`=sub.`subjectNo`
RIGHT JOIN 以右表为主
LEFT JOIN 以左表为主
INNER JOIN 左右两个表都有的才是
自连接
自己的表和自己的表连接,核心:一张表拆为两张表即可
父类
categoryid | categoryName |
2 | 信息技术 |
3 | 软件开发 |
5 | 美术设计 |
子类
pid | categoryid | categoryName |
3 | 4 | 数据库 |
2 | 8 | 办公信息 |
3 | 6 | web开发 |
5 | 7 | 美术设计 |
操作:查询父类对应子类关系
父类 | 子类 |
信息技术 | 办公信息 |
软件开发 | 数据库 |
软件开发 | web开发 |
美术设计 | ps技术 |
-- 查询父子信息
SELECT a.`categroryName` AS `父栏目`,b.`categroryName` AS `子栏目`
FROM `catgroy` AS a,`catgroy` AS b
WHERE a.`categoryid`=b.`pid`
-- 查询学员所属的年级(学号,学生的姓名,年级)
SELECT studentNo,studentName,gradeName
FROM student s
INNER JOIN `grade` g
ON s.`GradeId`=g.`GradeId`
4.5、分页和排序
排序
-- =======================分页 limit 和排序 order by ======================
-- 排序:升序 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` = '数据结构'
ORDER BY `StudentResult` DESC
分页
-- 为什么要分页?
-- 缓解数据库压力,给人的体验更好
-- 分页,每页只显示五条数据
-- 语法 : limit 起始值 ,页面的大小
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` = '数据结构'
ORDER BY `StudentResult` DESC
LIMIT 0,5 -- 从第0个数据开始,向后查询五个数据
-- 第一页 LIMIT 0,5
-- 第二页 LIMIT 5,5
-- 第三页 LIMIT 10,5
-- 第N页 LIMIT (n-1)*pageSize,pageSize
-- 【pageSize : 页面大小】
-- 【(n-1)*pageSize:起始值】
-- 【n : 当前页】
-- 【总页数 = 数据总数/页面大小】
语法:limit 查询下标起始值,pageSize
思考题:
-- 思考
-- 查询 JAVA大一学年 课程成绩排名前十的学生,并且分数要大于80的学生信息(学号,姓名,课程名称,分数)
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 s.`StudentResult`>80 AND `SubjectName`='JAVA大一学年'
ORDER BY `StudentResult` DESC
LIMIT 0,10
4.6、子查询
where(这个值是计算出来的)
本质:在where语句中嵌套一个子查询语句
-- ========================where==========================
-- 1、查询 数据库结构-1 的所有考试结果(学号,科目编号,成绩)
-- 方式一:使用连接查询
SELECT `StudentNo`,r.`SubjectNo`,`SubjectResult`
FROM `result` AS r
INNER JOIN `subject` AS sub
ON s.`SubjectNo` = sub.`SubjectNo`
WHERE `SubjectName`='数据库结构-1'
ORDER BY `SubjectResult` DESC
-- 方式二:使用子查询(由里及外)
SELECT `StudentNo`,`SubjectNo`,`SubjectResult`
FROM `result` AS r
WHERE `SubjectNo`=(
-- 查询所有数据库结构-1的学生学号
SELECT `SubjectNo` FROM `subject`
WHERE `SubjectName` = '数据库结构-1'
)
ORDER BY `SubjectResult` DESC
-- 高等数学-2 分数不小于80分的学生的学号和姓名
-- 方式一:使用连接查询
SELECT s.`StudentNo`,s.`StudentName`
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 `SubjectResult`>80 AND `SubjectName`='高等数学-2'
-- 方式二:使用子查询(由里及外)
SELECT `StudentNo`,`StudentName` FROM `student` WHERE `StudentNo` IN (
SELECT `StudentNo` FROM `resulr` WHERE `SubjectResult`>80 AND `SubjectNo` = (
SELECT `SubjectNo` FROM `subject` WHERE `SubjectName` = '高等数学-2'
)
)
4.7、分组过滤
-- 查询不同课程的平均分,最高分,最低分,平均分大于80
-- 核心:根据不同的课程分组
SELECT r.`SubjectName` , AVG(`SubjectResult`) AS 平均分,MAX(`SubjectResult`) AS 最高分 ,MIN(`SubjectResult`) AS 最低分
FROM `result` AS r
INNER JOIN `subject` AS sub
ON r.`SubjectNo`=sub.`SubjectNo`
GROUP BY r.`SubjectNo` -- 通过什么字段来分组
HAVING 平均分>80