狂神说MySQL - 你的雷哥 - 博客园 (cnblogs.com)
数据库基础
数据库操作命令
结构化查询语句分类
创建数据表
数据值和列类型
创建表的实例
MyIsam和INnodb对比
修改表内容
外键
DML语言,增删改查
DQL语言
注意不能用=null要用is null
表连接
排序和分页
子查询
MYSQL函数
事务和索引
-- 使用set语句来改变自动提交模式 SET autocommit = 0; /*关闭*/ SET autocommit = 1; /*开启*/ -- 注意: --- 1.MySQL中默认是自动提交 --- 2.使用事务时应先关闭自动提交 -- 开始一个事务,标记事务的起始点 START TRANSACTION -- 提交一个事务给数据库 COMMIT -- 将事务回滚,数据回到本次事务的初始状态 ROLLBACK -- 还原MySQL数据库的自动提交 SET autocommit =1; -- 保存点 SAVEPOINT 保存点名称 -- 设置一个事务保存点 ROLLBACK TO SAVEPOINT 保存点名称 -- 回滚到保存点 RELEASE SAVEPOINT 保存点名称 -- 删除保存点
/* 课堂测试题目 A在线买一款价格为500元商品,网上银行转账. A的银行卡余额为2000,然后给商家B支付500. 商家B一开始的银行卡余额为10000 创建数据库shop和创建表account并插入2条数据 */ CREATE DATABASE `shop`CHARACTER SET utf8 COLLATE utf8_general_ci; USE `shop`; CREATE TABLE `account` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(32) NOT NULL, `cash` DECIMAL(9,2) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO account (`name`,`cash`) VALUES('A',2000.00),('B',10000.00) -- 转账实现 SET autocommit = 0; -- 关闭自动提交 START TRANSACTION; -- 开始一个事务,标记事务的起始点 UPDATE account SET cash=cash-500 WHERE `name`='A'; UPDATE account SET cash=cash+500 WHERE `name`='B'; COMMIT; -- 提交事务 # rollback; SET autocommit = 1; -- 恢复自动提交
#创建时加索引 CREATE TABLE `Grade111`( `GradeID` INT(11) AUTO_INCREMENT, `GradeName` VARCHAR(32) NOT NULL, `GradeName1` VARCHAR(32) NOT NULL, PRIMARY KEY(`GradeID`), KEY(`GradeName`) ) #创建后加索引 ALTER TABLE `grade111` ADD INDEX UNIQUE(`GradeName`); ALTER TABLE `grade111` ADD INDEX Key(`GradeName`); ALTER TABLE `grade111` ADD INDEX PRIMARY KEY(`GradeName`); create index `drade111` on grade111(`GradeName`)
三大范式
连接池管理
视图
触发器
存储过程和触发器的区别
SET GLOBAL sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; #https://blog.csdn.net/qq_45060236/article/details/105357666修改配置group by 出现的无法处理8.0以上其他字段报错的问题 create table Student(SID varchar(10),Sname varchar(10),Sage datetime,Ssex VARCHAR(10)); insert into student VALUES('01', '赵雷', '1990-01-01' , '男') insert into Student values('02' , '钱电' , '1990-12-21' , '男'); insert into Student values('03' , '孙风' , '1990-12-20' , '男'); insert into Student values('04' , '李云' , '1990-12-06' , '男'); insert into Student values('05' , '周梅' , '1991-12-01' , '女'); insert into Student values('06' , '吴兰' , '1992-01-01' , '女'); insert into Student values('07' , '郑竹' , '1989-01-01' , '女'); insert into Student values('09' , '张三' , '2017-12-20' , '女'); insert into Student values('10' , '李四' , '2017-12-25' , '女'); insert into Student values('11' , '李四' , '2012-06-06' , '女'); insert into Student values('12' , '赵六' , '2013-06-13' , '女'); insert into Student values('13' , '孙七' , '2014-06-01' , '女'); insert into Student values('14' , '孙ba' , '2014-09-01' , '女'); create table Teacher(TId varchar(10),Tname varchar(10)); insert into Teacher values('01' , '张三'); insert into Teacher values('02' , '李四'); insert into Teacher values('03' , '王五'); create table Course(CId VARCHAR(10),Cname nvarchar(10),TId VARCHAR(10)); insert into Course values('01' , '语文' , '02'); insert into Course values('02' , '数学' , '01'); insert into Course values('03' , '英语' , '03'); create table SC(SId varchar(10),CId varchar(10),score decimal(18,1)); insert into SC values('01' , '01' , 80); insert into SC values('01' , '02' , 90); insert into SC values('01' , '03' , 99); insert into SC values('02' , '01' , 70); insert into SC values('02' , '02' , 60); insert into SC values('02' , '03' , 80); insert into SC values('03' , '01' , 80); insert into SC values('03' , '02' , 80); insert into SC values('03' , '03' , 80); insert into SC values('04' , '01' , 50); insert into SC values('04' , '02' , 30); insert into SC values('04' , '03' , 20); insert into SC values('05' , '01' , 76); insert into SC values('05' , '02' , 87); insert into SC values('06' , '01' , 31); insert into SC values('06' , '03' , 34); insert into SC values('07' , '02' , 89); insert into SC values('07' , '01' , null); insert into SC values('07' , '03' , 98); #1.1查询01课程比02课程成绩高的学生信息及课程分数 01 02都存在 *****************************同表内的字段进行比较可以 #case when then else end 对分组后的值选择满足条件的值,如max(case when 条件 then 输出 else 输出 end )为选择出满足条件的输出结果中的最大值,如果都不满足条件就输出else里的变量 SELECT Student.* ,MAX(case when sc.CId='01' then score end) as C1,MAX(case when sc.CId='02' then score end) as C2 from student LEFT JOIN SC on student.Sid = sc.SId GROUP BY SID #1.2查询01课程比02课程成绩高的学生信息及课程分数 01存在 02可能不存在 SELECT student.*, MAX(case when sc.CId='01' then score end) as C1 ,Max(case when sc.CId='02' then score end) as C2 from student LEFT JOIN sc on student.SID = sc.SId GROUP BY student.SID HAVING C1 is not null and c1>c2; #1.3查询01课程分数不存在但02存在 select *, max(case when sc.CId='01' then score end ) as C1,max(case WHEN sc.CId='02' then score end) as c2 from sc GROUP BY sc.SId HAVING c1 is null and c2 is not null; ##2.查询平均成绩大于等于60的同学的学生编号和学生姓名和平均成绩 SELECT student.SID,student.Sname,AVG(sc.score) as s from student LEFT JOIN sc on student.SID=sc.SId GROUP BY sc.SId HAVING s>60; SELECT sid,sname,(SELECT AVG(score) from sc where sc.SId=student.SId GROUP BY sc.SId HAVING (AVG(score) >= 60)) from student; #查询SC表存在成绩的学生信息 SELECT * from student where sid in (select sid from sc where score is not null) SELECT student.* from student,sc where student.SID=sc.SId and sc.score is not null GROUP BY sc.SId; #4 查询所有学生的学生编号、学生姓名、选课总数、所有课程的总成绩(各科成绩) SELECT student.SID,student.Sname,COUNT(*),sum(sc.score) from student LEFT JOIN sc on student.SID=sc.SId GROUP BY student.SId; #4.1 查询所有学生的学生编号、学生姓名、选课总数、所有课程的总成绩(有成绩) SELECT student.SID,student.Sname,COUNT(*),sum(sc.score) from student INNER JOIN sc on student.SID=sc.SId GROUP BY student.SId; #5.查询李姓老师的数量 SELECT count(*) from teacher where Tname LIKE '李%' #6.查询学过张三老师课程的学生的信息 SELECT student.* from student where SID in (SELECT SID from sc where CId in (SELECT CID from course where TId IN (SELECT TID from teacher where Tname='张三'))); SELECT student.* from student,sc,teacher,course WHERE student.SID=sc.SId and sc.CId=course.CId and course.TId = teacher.TId and Tname='张三'; #7.查询没有学全所有课程的同学的信息 SELECT student.*,count(student.SID) as num from student LEFT JOIN sc on student.SID=sc.SId GROUP BY student.SID HAVING num<(SELECT count(*) from course); #8.查询至少一门课与学号为‘01’的同学所学相同的同学的信息 SELECT student.* from student where student.SID in (SELECT distinct sc.SId from sc where sc.CId in (SELECT CId from sc where sc.SId='01') and sc.SId != '01') #9.查询和01同学课程完全相同的学生的信息 SELECT * from student where SID in (SELECT SID from sc where sc.CId in (SELECT CID from sc where sc.SId='01') GROUP BY SID HAVING COUNT(CId)=(SELECT COUNT(*) from sc where sc.SId='01')) #10.查询没学过‘张三’老师教授的任一门课程的学生姓名 SELECT * from student WHERE student.SID not in (SELECT sid from sc,course,teacher WHERE sc.SId and sc.CId = course.CId and course.TId=teacher.TId and teacher.Tname='张三'); #11.查询两门及以上不及格课程的同学的学号,姓名和平均成绩 SELECT student.SID,Sname,AVG(sc.score) from student,sc where student.SID=sc.SId GROUP BY sc.SId HAVING student.SID in (SELECT sid from sc where score<60 GROUP BY SId HAVING count(CId)>=2); #12.检索01课程分数小于60,按分数降序排列的学生信息 SELECT student.*,sc.score from student,sc where student.SID=sc.SId and sc.score < 60 and sc.CId='01' ORDER BY sc.score DESC; #13.查询平均成绩由高到低显示所有学生的所有课程的成绩及平均成绩 ******************************************* -- SELECT score,AVG(score) as av from sc GROUP BY sid ORDER BY av desc; SELECT * from sc left JOIN (SELECT sid,avg(score) as av from sc GROUP BY sid )r on sc.SId= r.sid ORDER BY av DESC; -- SELECT *,avg(score) as av from sc GROUP BY sid order by av desc; #14.查询各科成绩的最高分、最低分和平均分 SELECT CId,max(score),min(score),avg(score) from sc GROUP BY cid; #15.按各科成绩进行排序,并显示排名,成绩重复时保留名次空缺 -- SELECT * from student LEFT JOIN sc on sc.SId=student.SID GROUP BY CId order by score desc; #https://blog.csdn.net/liyang_nash/article/details/99641571 select a.cid,a.sid,a.score,count(b.score)+1 as rank_ from sc a #count(b.score)+1 as rank_,b.score代表某个学生该科目比其分数高的分数的总个数,+1表示其排名,没有比起高的就排第一 left join sc b on a.cid=b.cid and a.score<b.score group by a.cid,a.sid #再次用学号分组的原因是保证每个科目所有的学生作为一个个体都显示出来 order by a.cid,rank_ asc; select a.cid,a.sid,a.score from #无法显示排名 sc a GROUP BY a.CId,a.SId order by a.cid,a.score DESC; #15.1 按各科成绩进行排序,并显示排名,成绩重复时合并名次 select a.cid,a.sid,a.score,count(DISTINCT b.score)+1 as rank_ from sc a #count(b.score)+1 as rank_,b.score代表某个学生该科目比其分数高的分数的总个数,+1表示其排名,没有比起高的就排第一 left join sc b on a.cid=b.cid and a.score<b.score group by a.cid,a.sid #再次用学号分组的原因是保证每个科目所有的学生作为一个个体都显示出来 order by a.cid,rank_ asc; #16.查询学生的总成绩,并进行排名,总分重复时保留名次空缺 SELECT SID,sum(sc.score) as num from sc #无法直接算出排名,可以参考15,两个表进行连接,找出比起总成绩大的个数 GROUP BY sc.SID ORDER BY num DESC; SELECT a.sid,a.aa as score,count(b.bb)+1 as rank_ from (SELECT *,sum(score) as aa from sc GROUP BY SId )a LEFT JOIN (SELECT *,sum(score) as bb from sc GROUP BY sid)b on a.aa < b.bb GROUP BY a.SID order by rank_; #16.1查询学生的总成绩,并进行排名,总分重复时合并名次 SELECT a.sid,a.aa as score,count(DISTINCT b.bb)+1 as rank_ from (SELECT *,sum(score) as aa from sc GROUP BY SId )a LEFT JOIN (SELECT *,sum(score) as bb from sc GROUP BY sid)b on a.aa < b.bb GROUP BY a.SID order by rank_; #17.统计各科成绩各分数段的人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] SELECT course.CId,course.Cname,sum(case when score>85 then 1 else 0 end) as s1, sum(case when score>70 and score<=85 then 1 else 0 end) as s2, sum(case when score>60 and score<=70 then 1 else 0 end) as s3, sum(case when score<=60 then 1 else 0 end) as s4 from sc as a,course where a.CId=course.CId GROUP BY course.CId #18.查询各科成绩前三名的记录 SELECT sc.CId,sc.SId,sc.score from sc #该方法无法获取排名名词,需要进行和自己连表找出比自己分数高的学生的总数,在15基础上修改 GROUP BY sc.CId,sc.SId ORDER BY sc.CId,sc.score DESC SELECT sc.CId,sc.SId,sc.score,count(b.score)+1 as num #涉及到名次的自己单独这个表无法完成计算,可以通过和自己进行多表连接进行比较获取比自己大的个数作为排名。 from sc LEFT JOIN sc as b on sc.CId=b.CId and sc.score<b.score GROUP BY sc.CId,sc.SId HAVING num <= 3 ORDER BY sc.CId,num asc #19.查询每门课选修的学生人数 SELECT cid,count(*) from sc GROUP BY sc.CId #20.查询出只修两门课程的学生学号和姓名 SELECT sc.sid,sname,count(sc.SId) as num from sc,student where sc.SId=student.SID GROUP BY sc.sid HAVING num=2 #21.查询男生、女生人数 SELECT student.Ssex,count(student.Ssex) from student GROUP BY student.Ssex #22.查询名字中带有风字的学生信息 SELECT * from student where student.Sname LIKE '%风%'; #24.查询1990年出生的学生名单 SELECT * from student where year(student.Sage)=1990; #25.查询每门课的平均成绩,结果按平均成绩降序排列,若平均成绩相同时,则按课程号升序排列 SELECT sc.CId, avg(sc.score) as av from sc GROUP BY sc.CId ORDER BY av desc,sc.CId #26.查询平均成绩≥85的所有学生的学号、姓名和平均成绩 SELECT student.SID,student.Sname,AVG(sc.score) as num from sc,student where sc.SId=student.SID GROUP BY sc.SId HAVING num>=85; #27.查询课程名称为数学,且分数低于60的学生姓名和分数 SELECT student.Sname,sc.score from student,sc,course WHERE student.SID=sc.SId and course.Cname='数学' and sc.score<60 and course.CId=sc.CId; #28.查询所有学生的课程及分数情况 SELECT student.Sname,course.Cname,sc.score from student,sc,course where student.SID=sc.SId and sc.CId=course.CId #29.查询任何一门课程成绩在70分以上的学生姓名、课程名称和分数 SELECT student.Sname,course.Cname,sc.score from sc,student,course where sc.SId=student.SID and sc.CId=course.CId and student.SID in (SELECT sid from sc where sc.score>=70) SELECT student.Sname,course.Cname,sc.score from sc,student,course where sc.SId=student.SID and sc.CId=course.CId and student.SID in (SELECT sid from sc where sc.score>=70) #30.查询存在不及格的课程 SELECT DISTINCT course.Cname from sc,course where sc.CId=course.CId and course.CId in (SELECT CId from sc where sc.score < 60) #31.查询课程编号为01且课程成绩在80分以上的学生学号和姓名 SELECT student.SID,student.Sname from sc,student where sc.SId=student.SID and sc.CId='01' and sc.score>=80 #32.求每门课程的学生人数 SELECT count(*) from sc GROUP BY sc.CId #33.成绩不重复,查询选张三老师授课的学生中,成绩最高的学生信息及其成绩 SELECT student.*,sc.score from student,sc,course,teacher where student.SID=sc.SId and sc.CId=course.CId and course.TId=teacher.TId and teacher.Tname='张三' order by score desc LIMIT 0,1; #34.成绩重复,查询选李四老师授课的学生中,成绩最高的学生信息及其成绩 SELECT student.*,sc.score from student,sc,course,teacher where student.SID=sc.SId and sc.CId=course.CId and course.TId=teacher.TId and teacher.Tname='李四' and sc.score = (SELECT max(sc.score) from sc,course,teacher where sc.CId=course.CId and course.TId=teacher.TId and teacher.Tname='李四') #35.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩 ******** 表里面的不同行记录进行比较可以考虑同一个表进行连接比较, SELECT * from sc as a left join sc as b on a.sid=b.sid and a.CId<>b.CId where a.score=b.score #36.查询每门课程成绩最好的前两名 ***** SELECT sc.CId,sc.SId,sc.score,count(b.score)+1 as num from sc LEFT JOIN sc b on sc.score < b.score and sc.cid=b.cid GROUP BY sc.sid,sc.CId HAVING num<=2 ORDER BY sc.CId,num #37.统计每门课程的选修人数,超过5人 SELECT count(*) as num from sc GROUP BY sc.CId HAVING num>5; #38.查询至少选修了两门课程的学生学号 SELECT sc.SId,count(sc.SId) as num from sc GROUP BY sc.SId HAVING num>=2; #39.查询选修了全部课程的学生信息 SELECT student.*,count(sc.CId) as num from student,sc where student.SID=sc.SId GROUP BY sc.SId HAVING num=(SELECT count(*) from course) #40.查询各学生的年龄,只按年份计算 SELECT student.Sname,YEAR(now())-YEAR(student.Sage) from student #41.按出生日期来算,当前月日<出生月日,则年龄减1 SELECT student.Sname,(case when ((month(now())-month(student.Sage)=0 and day(now())-day(student.Sage)>=0) or month(now())-month(student.Sage)>0)then YEAR(now())-YEAR(student.Sage) else YEAR(now())-YEAR(student.Sage) -1 end ) from student #42.查询本周过生日的同学 select date_format(now(),'%w'); #查询今天星期几 set @mon=(select subdate(curdate(),date_format(curdate(),'%w')-1)); #本周一的日期 set @sun=(select adddate(curdate(),7-date_format(now(),'%w'))); #本周日的日期 select sid from student where date_format(sage,'%m-%d')<=date_format(@sun,'%m-%d') and date_format(sage,'%m-%d')>=date_format(@mon,'%m-%d'); SELECT curdate() SELECT now() #43.查询下周过生日的同学 set @nextMon = (SELECT ADDDATE(CURDATE(),7-date_format(now(),'%w')+1)) set @nextSun = (SELECT ADDDATE(CURDATE(),7-DATE_FORMAT(now(),'%w')+7)) SELECT student.Sname,student.Sage from student where date_format(Sage,'%m-%d')>= DATE_FORMAT(@nextMon,'%m-%d') and date_format(Sage,'%m-%d')<= DATE_FORMAT(@nextSun,'%m-%d'); #44.查询本月过生日的同学 SELECT * from student where MONTH(now())=MONTH(student.Sage) #45.查询下月过生日的同学 SELECT * from student where MONTH(now())+1=MONTH(student.Sage)