子查询的功能比表连接功能大
SELECT ……FROM 表名 WHERE EXISTS(子查询);
子查询有返回结果:EXISTS查询结果为TRUE
子查询无返回结果:EXISTS查询结果为FALSE,外层查询不执行
EXISTS:执行效率高 速度快
EXISTS是不相关子查询,如查询不准确,范围扩大,可进行相互关联(就是相关子查询),使其查询条件与执行结果有关联。
任何允许使用表达式的地方都可以使用子查询
嵌套在父查询SELECT语句的子查询可包括
SELECT子句
FROM子句
WHERE子句
GROUP BY子句
HAVING子句
只出现在子查询中而没有出现在父查询中的列不能包含在输出列中
分组查询
SELECT……FROM 表名
WERE……
GROUP BY ……
分组删选语句:
SELECT …… FROM 表名
WHERE ……
GROUP BY ……
HAVING……
WHERE子句
用来筛选 FROM 子句中指定的操作所产生的行
GROUP BY子句
用来分组 WHERE 子句的输出
HAVING子句
用来从分组的结果中筛选行
内连接:INNER JOIN
SELECT ……
FROM 表1
INNER JOIN 表2
ON ……
外连接:左外链接(LEFT JOIN)一个主表 一个从表,从表配合主表
右外连接(RIGHT JOIN)
左外连是左边为主表,右外联是主表
CREATE TEMPORARY TABLE 表名(查询语句);
事务:
事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作
多个操作作为一个整体向系统提交,要么都执行、要么都不执行
事务是一个不可分割的工作逻辑单元
事务具备的属性
原子性:事务是一个完整的操作,事务的各步操作是不可分的(原子的),要么都执行,要么都不执行
一致性:当事务完成时,数据必须处于一致状态
隔离性:并发事务之间彼此隔离、独立,它不应以任何方式依赖于或影响其他事务
持久性:事务完成后,它对数据库的修改被永久保持
mysql支持事务存储的引擎有InnoDB和BDB
开始事务
BEGIN;或START TRANSAC TION;
提交事务:COMMIT;#所有语句都是成功就COMMIT(提交)
回滚(撤销)事务:ROLLBACK;#错误就ROLLBACK(撤回)
默认情况下,每条单独的SQL语句视为一个事务
关闭默认提交状态后,可手动开启、关闭事务
关闭/开启自动提交状态
SET autocommit = 0|1;
0为关闭自动提交;1为开启自动提交
注:关闭自动提交后,从下一条SQL语句开始则开启新事务,需使用COMMIT或ROLLBACK语句结束该事务
MySQL默认提交事务,不能回滚。
#最近一次考试成绩80以上的前五的学号和分数
SELECT r.studentno,r.studentresult FROM result r
WHERE subjectno=(SELECT subjectno FROM SUBJECT WHERE subjectname='python')
AND examdate=(SELECT MAX(examdate) FROM SUBJECT WHERE
subjectno=(SELECT subjectno FROM SUBJECT WHERE subjectname='python'))
AND studentResult>=80
ORDER BY studentresult DESC
LIMIT 5;
#用EXISTE
#不相关子查询
#相关子查询
SELECT r.studentNo,r.studentresult FROM result r
WHERE EXISTS(
SELECT subjectno FROM SUBJECT st WHERE subjectname='python'
AND r.`subjectNo`=st.`subjectNo`
)AND examdate=(
SELECT MAX(examdate) FROM result rt WHERE subjectno=(
SELECT subjectno FROM SUBJECT st WHERE subjectname='python'
)
)
AND r.studentresult>=80
ORDER BY studentresult DESC
LIMIT 5;
#如果有S2的学生,就查询参加S2学科考试的学员学号、科目编号、考试成绩,考试时间
SELECT studentno,subjectno,studentresult,examdate FROM result r
WHERE EXISTS(
SELECT *FROM student1 s WHERE gradeid=(SELECT gradeid FROM grade
WHERE gradename='s2' AND r.studentno=s.studentno)
)AND subjectno IN
(SELECT subjectno FROM SUBJECT WHERE
gradeid=(SELECT gradeid FROM grade WHERE gradename='s2'));
#分组查询每门课程的平均分数
SELECT subjectno,AVG(studentresult) FROM result
GROUP BY subjectno
ORDER BY AVG(studentresult) DESC;
#分别统计每个年级的男生和女生人数
SELECT gradeid,sex,COUNT(*) FROM student1
GROUP BY gradeid,sex
ORDER BY gradeid;
# INNER JOIN内连接语句
SELECT studentname,subjectno,studentresult FROM student1
INNER JOIN result ON student1.`studentNo`=result.`studentNo`;
#查询学生编号 科目名称 学生成绩
SELECT studentno,subjectname,studentresult FROM result INNER JOIN
SUBJECT ON result.`subjectno`=subject.`subjectno`;
#查询学生姓名 科目名称 学生成绩 大于80的同学
SELECT studentname,subjectname,studentresult FROM student1
INNER JOIN result ON student1.`studentNo`=result.studentno
INNER JOIN SUBJECT ON result.`subjectNo`=subject.`subjectNo`
WHERE studentresult>=80;
#用左外连的方式LEFT JOIN
SELECT studentname,subjectno,studentresult FROM student1
LEFT JOIN result ON student1.studentno=result.`studentno`;
#查询参加考试的学生 用三种方法
SELECT * FROM student1
WHERE EXISTS(SELECT * FROM result WHERE studentno=student1.studentno);
SELECT * FROM student1
WHERE studentno IN (SELECT studentno FROM result);
SELECT * FROM student1 INNER JOIN result ON
student1.`studentNo`=result.`studentNo`;
#开启事务
BEGIN;
UPDATE result SET studentresult=60 WHERE studentno=1501;
COMMIT;
#通过事物插入数据
BEGIN;
INSERT INTO result (studentno,subjectno,examdate,studentresult)
VALUES(1501,1,NOW(),63);
INSERT INTO result(studentno,subjectno,examdate,studentresult)
VALUES(1505,1,NOW(),56);
COMMIT;