MySQL
day2_2023.9.5
SQL查询语句
基本的条件查询
模糊查询
like 通配符: _ 或者 %
SELECT * FROM emp WHERE ename LIKE ‘%S%’;
分页查询
limit关键字
-- limit分页 :limit 值1,值2
-- 值1表示从第几行开始返回数据
-- 值2表示每页显示几条数据
-- 已知 总条数 totalCount 20 、每页显示的数据条数 num 5 -- 总页数 totalPage 4
-- 点击的页数 page
-- (page-1) * num
SELECT * FROM emp LIMIT 0,5;
排序
order by asc/desc ,默认是asc,从小到大 , desc是从大到小
– 排序
SELECT * FROM emp ORDER BY sal DESC;
分组
group by 语句
– group by, 如果没有出现在group by后面的字段,也不能出现在select后面
– 求每个部门的人数、平均工资
SELECT deptno,COUNT(1),AVG(sal) FROM emp GROUP BY deptno;
– 分部门、分职业求他们的平均工资
SELECT deptno,job,AVG(sal) FROM emp GROUP BY deptno,job;
过滤分组
having 语句 一般用来过滤 group by之后的结果
– 查询 哪个部门的 平均工资超过了 2000
SELECT deptno,AVG(sal) AS avg_sal FROM emp GROUP BY deptno HAVING avg_sal > 2000;
– 查询哪个部门的哪个岗位的平均工资低于1000
SELECT deptno,job,AVG(sal) FROM emp GROUP BY deptno,job HAVING AVG(sal) <1000;
– 查询哪个岗位的平均工资超过了4000
SELECT job,AVG(sal) FROM emp GROUP BY job HAVING AVG(sal) > 4000;
– having 主要用来过滤分组之后的数据,where是分组之前的条件过滤
– where 不可以使用聚合函数,having后面可以使用聚合函数
SELECT 5
FROM 1
WHERE 2
GROUP BY 3
HAVING 4
ORDER BY 6
多表查询
子查询
-- 子查询
-- from型 将子查询作为新表
-- where型 将子查询结果作为条件
-- exists型 判断子查询结果是否成立
-- where型
-- 使用子查询,查询员工中,工资最高的员工所在部门。
-- 先查询最高工资,再查询所在部分
SELECT MAX(sal) FROM emp;
SELECT * FROM emp WHERE sal = (SELECT MAX(sal) FROM emp);
-- 单行子查询 子查询的结果是单行结果,将来使用单行比较运算符完成运算
-- 多行子查询 子查询的结果是多行结果,可以用in操作符
-- 通过子查询,查询所有选修刘阳老师任意课程的学生信息,(如果学生这门课有成绩,表示选修了)
-- 1,查询老师的编号
SELECT tno FROM teacher WHERE tname = '刘阳';
-- 2,通过老师编号,查到教的课程编号
SELECT cno FROM course WHERE tno =
(SELECT tno FROM teacher WHERE tname = '刘阳')
-- 3,所有课程编号中,有成绩的学生的学号
SELECT sno FROM sc WHERE cno IN
(SELECT cno FROM course WHERE tno =
(SELECT tno FROM teacher WHERE tname = '刘阳'))
AND score IS NOT NULL;
-- 4,通过学号查到学生信息
SELECT * FROM student WHERE sno IN
(SELECT sno FROM sc WHERE cno IN
(SELECT cno FROM course WHERE tno =
(SELECT tno FROM teacher WHERE tname = '刘阳'))
AND score IS NOT NULL)
-- any all
-- 查询任意一门课,超过了70分的学生的信息
SELECT DISTINCT sno FROM sc WHERE score > 70;
SELECT * FROM student WHERE sno IN (SELECT DISTINCT sno FROM sc WHERE score > 70);
-- 找出比李四任意一门成绩高的其他学生的学号
SELECT sno FROM student WHERE sname = '李四';
SELECT score FROM sc WHERE sno =
(SELECT sno FROM student WHERE sname = '李四');
-- 找比李四成绩高的
SELECT DISTINCT sno FROM sc WHERE score > ANY
(SELECT score FROM sc WHERE sno =
(SELECT sno FROM student WHERE sname = '李四'))
AND sno != (SELECT sno FROM student WHERE sname = '李四')
-- 找到比李四所有成绩都低的学生信息
/*
SELECT * FROM sc WHERE score < all
(SELECT score FROM sc WHERE sno =
(SELECT sno FROM student WHERE sname = '李四'))
AND sno != (SELECT sno FROM student WHERE sname = '李四')
*/
-- s001(85,75,60)< all(80,70) -- 不适用与比较对象有多个值的情况
-- s001(85) ,s002(65) <all (80,70) -- 适用于比较的对象只有一个值的情况
-- 找到比所有女生年龄都大的学生的信息
SELECT sage FROM student WHERE ssex = '女';
SELECT * FROM student WHERE sage > ALL
(SELECT sage FROM student WHERE ssex = '女')
连接查询
内连接
– inner join on
– 交叉连接 cross join on
– 逗号 ,
外连接
– 左外连接left join
– 右外连接right join
– 全外连接 full join(mysql中不支持)
内连接和外连接的区别?
内连接查询是将多张表做笛卡尔积,根据条件将不符合条件的记录过滤掉,留下符合条件的
外连接查询的时候,需要指定一个基准表,基准表的数据会全部展示,不足的地方以null展示
左外连接以 左边的表 作为基准表,左边的表都显示
右外连接以右边的表作为基准表,右边的表全部显示
自连接
-- 使用内连接查询,返回每个学生学号、姓名、课程号、分数
SELECT s1.sno,sname,cno,score FROM student s1 INNER JOIN
sc s2 ON s1.sno = s2.sno
SELECT s1.sno,sname,cno,score FROM student s1 CROSS JOIN
sc s2 ON s1.sno = s2.sno
SELECT s1.sno,sname,cno,score FROM student s1,sc s2
WHERE s1.sno = s2.sno
-- 使用外连接查询,返回每个学生学号、姓名、课程号、分数
SELECT s1.sno,sname,cno,score FROM student s1 LEFT JOIN
sc s2 ON s1.sno = s2.sno
SELECT s1.sno,sname,cno,score FROM student s1 RIGHT JOIN
sc s2 ON s1.sno = s2.sno
-- 查询所有课程成绩高于80的同学的学号、姓名;
SELECT s1.sno,sname FROM student s1 INNER JOIN sc s2
ON s1.sno = s2.sno
GROUP BY sno,sname
HAVING MIN(score) > 80;
-- 查询课程编号“c002”的成绩比课程编号“c001”课程低的所有同学的学号、姓名;
SELECT s3.sno,s3.`sname` FROM sc s1,sc s2,student s3 WHERE
s1.`cno` = 'c002'
AND s2.`cno` = 'c001'
AND s1.`sno` = s2.`sno`
AND s1.`score` > s2.`score`
AND s1.`sno` = s3.`sno`
-- 查询平均成绩大于75 的所有学生的学号、姓名和平均成绩
SELECT * FROM (
SELECT s1.`sno` ,s1.sname, AVG(score) AS avg_score
FROM student s1 ,sc s2
WHERE s1.`sno` = s2.`sno`
GROUP BY s1.`sno`,s1.sname) t
WHERE avg_score > 75;
-- 查询课程名称为“J2SE”,且分数低于80 的学生姓名和分数
SELECT s1.`sname`,c1.`cname`,s2.`score` FROM student s1
INNER JOIN sc s2 ON s1.`sno` = s2.`sno`
INNER JOIN course c1 ON s2.`cno` = c1.`cno`
AND c1.`cname` = 'J2SE' AND s2.`score` < 80;
-- 查询选修“谌燕”老师所授课程的学生中,成绩最高的学生姓名及其成绩
-- 查询老师的tno
SELECT tno FROM teacher WHERE tname = '谌燕';
SELECT cno FROM course WHERE tno =
( SELECT tno FROM teacher WHERE tname = '谌燕')
SELECT MAX(score) FROM sc WHERE cno IN
( SELECT cno FROM course WHERE tno =
( SELECT tno FROM teacher WHERE tname = '谌燕'))
-- 将最高分和 课程编号带入查询,查询到信息
SELECT sname,score FROM student s1,sc s2
WHERE s1.sno = s2.sno
AND score = (SELECT MAX(score) FROM sc WHERE cno IN
( SELECT cno FROM course WHERE tno =
( SELECT tno FROM teacher WHERE tname = '谌燕')))
AND s2.cno IN ( SELECT cno FROM course WHERE tno =
( SELECT tno FROM teacher WHERE tname = '谌燕'));
-- 查询课程编号为c001 且课程成绩在80 分以上的学生的学号和姓名
SELECT s1.sno,sname FROM student s1 INNER JOIN sc s2
ON s1.sno = s2.`sno`
AND s2.`cno` = 'c001'
AND s2.`score` > 80;
-- 查询出只选修了一门课程的全部学生的学号和姓名
SELECT s1.sno,sname FROM
student s1 INNER JOIN sc s2
ON s1.sno = s2.`sno`
GROUP BY s1.sno
HAVING COUNT(1) =1;
-- 查询学过“c001”并且也学过编号“c002”课程的同学的学号、姓名
SELECT s1.sno,s1.`sname` FROM student s1 INNER JOIN sc s2 ON s1.sno = s2.`sno`
INNER JOIN sc s3 ON s2.`sno` = s3.`sno`
AND s2.`cno` = 'c001' AND s3.`cno` = 'c002'
AND s2.`score` IS NOT NULL
AND s3.`score` IS NOT NULL
-- 数据库事务
-- 事务一般就是指DML操作
-- 事务特性
-- 原子性 、一致性、隔离性 、 持久性
MySQL中手动开启事务 :start transaction;
-- 隔离级别
-- 事务并发 : 引起
-- 脏读 :读取到别的事务未提交的数据 (绝对不允许)
-- 虚读 :读到别的事务提交后修改的数据(允许发生)
-- 幻读 :读到数据的时候,两次读取的数据行数不一样(允许发生)
-- 隔离级别 解决上面的问题
-- Read Uncommited RU 读未提交
-- Read Commited RC 读已提交 Oracle
-- Repeatable Read RR 可重复读 MySQL
-- Serializable 可串行化
-- RU 出现以上三个问题
-- RC 解决 脏读
-- RR 解决 虚读 (加锁可以解决幻读)
-- Serializable 解决三个
-- 查询当前的隔离级别
SELECT @@global.tx_isolation; -- RR
SELECT @@session.tx_isolation; -- RR
SELECT @@tx_isolation;
-- 修改隔离级别
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL {
READ UNCOMMITTED |
READ COMMITTED |
REPEATABLE READ |
SERIALIZABLE |
}
SELECT * FROM test;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT @@session.tx_isolation;