+---------+-------------+------+-----+---------+-------+| Field |Type|Null|Key|Default| Extra |+---------+-------------+------+-----+---------+-------+| teaId |int(11)|NO| PRI |NULL||| teaName |varchar(20)|NO|| 待补 ||+---------+-------------+------+-----+---------+-------+
select student.*,t1.score as score01,t2.score as score02
from student,(select stuId,score from stuScore where stuScore.couId=1)as t1,(select stuId,score from stuScore where stuScore.couId=2)as t2
where t1.stuId = t2.stuId and t1.score>t2.score
and student.stuId=t1.stuId;
题2:查询"01"课程比"02"课程成绩低的学生的信息及课程分数(-类比重复-题1了)
select student.*,t1.score as score01,t2.score as score02
from student,(select stuId,score from stuScore where stuScore.couId=1)as t1,(select stuId,score from stuScore where stuScore.couId=2)as t2
where t1.stuId = t2.stuId and t1.score<t2.score
and student.stuId=t1.stuId;
题3:查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
select student.stuId,student.stuName,round(avg(stuScore.score),2)as Averge from
student innerjoin stuScore
on student.stuId=stuScore.stuId
groupby student.stuId
havingAVG(stuScore.score)>=60;
题4:查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩 – (包括有成绩的和无成绩的)
select student.stuId,student.stuName,(casewhenAVG(sc1.score)isnullthen0elseAVG(sc1.score)end)from
student
leftjoin stuScore as sc1
on student.stuId=sc1.stuId
groupby student.stuId
havingAVG(sc1.score)<60or AVGG(sc1.score)isnull;
题5:查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
#土方法,排序上有点小问题select student.stuId,student.stuName,t1.score as score01,t2.score as score02,t3.score as score03,((casewhen t1.score isnullthen0else t1.score end)+(casewhen t2.score isnullthen0else t2.score end)+(casewhen t3.score isnullthen0else t3.score end))as sumScore,((casewhen t1.score isnullthen0 else1 end)+(casewhen t2.score isnullthen0else1end)+(casewhen t3.score isnullthen0else1end))as count
from student
leftjoin(select*from stuScore where couId=1)as t1
on student.stuId=t1.stuId
leftjoin(select*from stuScore where couId=2)as t2
on t1.stuId = t2.stuId
leftjoin(select*from stuScore where couId=3)as t3
on t1.stuId=t3.stuId;#新方法,排序上无问题select student.stuId,student.stuName,COUNT(stuScore.couId)as count,SUM(stuScore.score)as sumScore
from student
leftjoin stuScore
on student.stuId=stuScore.stuId
groupby student.stuId;#优化一下,可以避免SUM结果出现null的情况,使用分支语法就可select student.stuId,student.stuName,COUNT(stuScore.couId)as count,(casewhenSUM(stuScore.score)isnullthen0elseSUM(stuScore.score)end)as sumScore
from student
leftjoin stuScore
on student.stuId=stuScore.stuId
groupby student.stuId;
题6:查询"李"姓老师的数量
selectcount(*)as count from teacher where teaName like'李%';
题7:查询学过"张三"老师授课的同学的信息
select student.*,course.couId,teacher.teaName
from teacher
leftjoin course on teacher.teaId=course.teaIdteaId
leftjoin stuScore on stuScore.couId=course.couId
leftjoin student on student.stuId=stuScore.stuId
where teacher.teaName='张三';
题8:查询没学过"张三"老师授课的同学的信息
select student.*from student
where student.stuId
notin(select stuScore.stuId from stuScore
where stuScore.couId
in(select course.couId from course leftjoin teacher on course.teaId=teacher.teaId where teacher.teaName='张老师'));
题9:查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
#法一:偏算术算法select student.*from student
where stuId
in(select stuId from stuScore
where couId in(1,2)groupby stuId
havingcount(*)!=1);#法二:偏表表联系select student.*from student
where stuId
in(select t1.stuId from(select*from stuScore where couId=1)as t1
innerjoin(select*from stuScore where couId=2)as t2
on t1.stuId=t2.stuId );
题10:查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
#法一:偏分表联系select student.*from student
where stuId
in(select stuId from stuScore where couId=1)and stuId
notin(select stuId from stuScore where couId=2);#法二:group by 分组往下探头#(每个学生都不存在只有一个成绩,在经典50题的表适用)select student.*from student
leftjoin stuScore
on student.stuId=stuScore.stuId
groupby student.stuId
havingcount(*)<=2andsum(couId)=4;#(1+3=4)#(当存在只有一个成绩的时候,就会冲昏‘3’=‘1+2’)#这里给couId加1,加强和运算后的独立#当一位数时:1-2-3--+1-->2-3-4#当二位数时:1+2-2+3-1+3--+1-->2+3-3+4-2+4-->5-7-6#此时一位和二位成绩存在已经无关,不能冲昏,【完成】select student.*from student
leftjoin stuScore
on student.stuId=stuScore.stuId
groupby student.stuId
havingcount(*)<=2andsum(stuScore.couId+1)in(2,4,6);
题11:查询没有学全所有课程的同学的信息
#比较优的方法select student.*from student
leftjoin stuScore
on student.stuId=stuScore.stuId
groupby student.stuId havingcount(couId)<(selectcount(*)from course);# having count(couId)<(select count(*) from course); # having SUM(couId)<(select SUM(couId) from course);#为什么不能直接count(course.couId),因为course表没在最外层的from范围内#杂但是理解简单的方法:表表联系select student.*,t1.score as score01,t2.score as score02,t3.score as score03
from student
leftjoin(select*from stuScore where couId=1)as t1
on student.stuId = t1.stuId
leftjoin(select*from stuScore where couId=2)as t2
on student.stuId = t2.stuId
leftjoin(select*from stuScore where couId=3)as t3
on student.stuId = t3.stuId
where t1.score isnullor t2.score isnullor t3.score isnull;
题12:查询至少有一门课与学号为"01"的同学所学相同的同学的信息
#第一个直觉是,集合问题#因为要先知道01同学的选课大集合,才能从总的若个集合中有交集就显示select student.*from student
leftjoin stuScore as t1
on t1.stuId=student.stuId
where t1.couId
in(select t2.couId from stuScoret2 where t2.stuId=1);
题13:查询和"01"号的同学学习的课程完全相同的其他同学的信息
#比较优的方法:用了一下couId+1的数字和运算区分#也是有点集合问题的直觉select student.*from student
leftjoin stuScore as t1
on student.stuId = t1.stuId
groupby student.stuId
havingsum(t1.couId+1)=(selectsum(t2.couId+1)from stuScore as t2 groupby t2.stuId having t2.stuId=1);
题14:查询没学过"张三"老师讲授的任一门课程的学生姓名
#无赖打法:一层一层拨开你的心,有点串联信息交流的意思,#需要的信息总是由一个又一个的系统的输出作为输入select student.*from student
where stuId notin(select stuScore.stuId from stuScore
where stuScore.couId=(select course.couId from course
where teaId=(select teaId from teacher
where teaName='张老师')));#表表联系:最后来个刺激select*from student
where stuId
notin(select stuId from stuScore
innerjoin course on stuScore.couId=course.couId
innerjoin teachereacher on teacher.teaId=course.teaId
where teaName='张老师');
题15:查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
#无赖打法:乱打一通select student.stuId,student.stuName,t1.avgScore
from student #学生信息来源innerjoin#平均成绩来源(平均成绩包含及格的成绩一起算)(select stuScore.stuId,avg(score)as avgScore
from stuScore
#必须重新回到成绩表获得平均成绩,而不是从拿到的不及格表拿到平均成绩groupby stuScore.stuId)as t1 on student.stuId=t1.stuId
where student.stuId
in(select temp1.stuId from(select*from stuScore as t1 where score <60)as temp1
groupby temp1.stuId havingcount(*)>=2);#拿到超2科的不及格成绩表#集合联系:#注意:如果再同一范围的语句中就算平均值就会被where语句给抢掉#比如:三个数,50,40,80#被where抢前后,计算的平均值只能是(50+40)/2#而不是正确意义上的(50+40+80)/3select student.stuId,student.stuName,AVG(t1.score)from student
leftjoin stuScore as t1 on student.stuId=t1.stuId
where t1.stuId
in(select t2.stuId from stuScore t2
where t2.score<60or t2.score isnullgroupby t2.stuId
havingcount(t2.stuId)>=2)groupby student.stuId;
题16:检索"01"课程分数小于60,按分数降序排列的学生信息
#垃圾题目select*from student
leftjoin(select*from stuScore where couId=1)as t1
on student.stuId=t1.stuId
where score<60orderby score desc;
#表表联系:汇总最后一击select student.stuName,t1.score as score01,t2.score as score02,t3.score as score03,t4.AvgScore
from student
leftjoin(select*from stuScore where couId=1)as t1 on student.stuId=t1.stuId
leftjoin(select*from stuScore where couId=2)as t2 on student.stuId=t2.stuId
leftjoin(select*from stuScore where couId=3)as t3 on student.stuId=t3.stuId
leftjoin(select temp1.stuId,avg(temp1.score)as AvgScore from stuScore as temp1 groupby temp1.stuId)as t4 on t4.stuId=student.stuId
orderby t4.AvgScore desc;#↑有个误区是在第四表连接中,容易用#left join stuScore on xx.stuId=xx.stuId group by student.stuId ...#是出现了类似的可以进行分组查询的新式表,但是实际上这张表是3个及以上所形成的的,#而你t4只跟student用on关联起来了,当你使用student的stuId的时候,就会视t1表不见#所以就会出现t1.score无法参与group by
#方法笨了点,“我丑但是我很温柔”,但是易懂:采用全count计数器计算率的问题#数据来源一张一张的表select
t1.couId '课程ID',t1.couName '课程名称',
t1.max '最高分',t1.min '最低分',t1.avg '平均分',
t2.cnt2/t1.cnt1 '及格率',t3.cnt3/t1.cnt1 '中等率',t4.cnt4/t1.cnt1 '优良率',t5.cnt5/t1.cnt1 '优秀率'from(select course.couId, course.couName,max(score)as max,min(score)as min,avg(score)as avg,count(*)as cnt1
from stuScore
leftjoin course on stuScore.couId=course.couId groupby course.couId)as t1 leftjoin(select stuScore.couId,count(*)as cnt2 from stuScore where score>=60groupby stuScore.couId
)as t2 on t1.couId=t2.couId
leftjoin(select stuScore.couId,count(*)as cnt3
from stuScore
where score>=70and score<80groupby stuScore.couId
)as t3 on t1.couId=t3.couId
leftjoin(select stuScore.couId,count(*)as cnt4
from stuScore
where score>=80and score<90groupby stuScore.couId
)as t4 on t1.couId=t4.couId
leftjoin(select stuScore.couId,count(*)as cnt5
from stuScore
where score>=90and score<=100groupby stuScore.couId
)as t5 on t1.couId=t5.couId
orderby t1.couId;#眨眼一看,一坨shit#新方法:偏算法判断类型,用条件判断做计时器,即01计时器select course.couId '课程ID',course.couName '课程名称',max(score)'最高分',min(score)'最低分',avg(score)'平均分',(sum(casewhen score>=60then1else0end)/count(*))as'及格率',(sum(casewhen score>=70and score<80then1else0end)/count(*))as'中等率',(sum(casewhen score>=80and score<90then1else0end)/count(*))as'优良率',(sum(casewhen score>=90and score<=100then1else0end)/count(*))as'优秀率'from stuScore leftjoin course on stuScore.couId=course.couId groupby course.couId;
题19:按各科成绩进行排序,并显示排名
#不显示排名就这样,简简单单,难就难在要显示排名select t1.*,course.couName,student.stuName from stuScore as t1 leftjoin student on t1.stuId=student.stuId leftjoin course on course.couId=t1.couId orderby t1.couId,t1.score desc;#那就要插入一个列,这个列在所存在的表也是没有。#只能引入一个变量了#而且这个变量要在couId一变就重新排列#用变量的时候,注意一下MySQL的非存储过程的执行过程也是有顺序的#这里要知道select到from这其中是挑选字段的范围#要在表构建完后才进行挑选,所以这里的语句是比from中表源后一些的#这也能解释为什么要先在from后跟一个变量定义或变量赋值#然而cross join 是为什么?#因为这个表连接,好像是没什么关系的连,它连on字段的联系都没有。select(@i:=casewhen@couIdFlow= t2.couId then@i+1else1end)as'NO.',(@couIdFlow:=t2.couId)as couId,
t2.couName,t2.score,t2.stuName
from(select@i :=0,@couIdFlow :=1)as forDefineValue
crossjoin(select t1.*,course.couName,student.stuName from stuScore as t1
leftjoin student on t1.stuId=student.stuId
leftjoin course on course.couId=t1.couId
orderby t1.couId,t1.score desc)as t2;
题20:查询学生的总成绩并进行排名
#如果这里,关于19题的变量有一定的见解后,也是比较简单了。#我们先不显示排名的进行sum排序一下,然后再加入显示排名的一列#比如这里,我们要借助i变量来显示,并依次每一条记录来+1往下显示就可以#然后需要定义变量或叫初始化变量的值#使用cross join这种无关痛痒的手法select(@i:=@i+1)as'NO.',t2.*from(select@i :=0)as forDefineValue
crossjoin(select student.stuId,student.stuName,sum(t1.score)as sumScore
from stuScore as t1
leftjoin student on student.stuId=t1.stuId
groupby t1.stuId
orderbysum(t1.score)desc)as t2;
题21:查询不同老师所教不同课程平均分从高到低显示
#这是一个比较直观的方法了,主要通过group by来划分#--因为版本问题,如果使用group by 后面只接一个字段的话,会报错#--主要还是因为full_group_by这个模式的原因#--好像是某个版本5.7.x之后,就默认开启了这个模式,叫什么依赖关系的#--这里,teacher表和course表都能一一对应#--所以用两个字段来分组好像也没什么关系了。#--据了解,好像是select所选中的字段中,除了聚合函数外,#--都要在group by中参与#--而实际中,却只是用了来自不同表的teaId和couId#--当更换course的couId为couName时候,又报错#--所以啊,初步认为跟“依赖关系”有关,我们在构建表表关系的时候#--用了teaId和couId#--而且我怀疑跟表设置主键或表之间构建关联的字段有点关系select tea.teaId,tea.teaName,cou.couId,cou.couName,avg(t1.score)as avgScore
from teacher as tea
leftjoin course as cou on tea.teaId=cou.teaId
leftjoin stuScore as t1 on t1.couId=cou.couId
groupby tea.teaId,cou.couId
orderbyavg(t1.score)desc;#方法二:#上面的方法是直接用三表联立,且group by建立在三表联立下#这就必须要group by 时候,选中select中的不同表的被联系字段#下面这种方法是把group by 框在某个内层表内select tea.teaId,tea.teaName,couAndAvg.*from teacher as tea
leftjoin(select course.*,avg(score)as avgScore
from course
leftjoin stuScore on course.couId=stuScore.couId
groupby couId
)as couAndAvg on tea.teaId=couAndAvg.teaId
orderby avgScore desc;
题22:查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
#土方法:我感觉有点无赖,使用了变量来排名,然后再联系学生IDselect student.*,rankTable.number as'NO.',rankTable.couId,rankTable.score
from student
leftjoin(select(@i:=casewhen@couIdFlow=t1.couId then@i+1else1end)as number,(@couIdFlow:=t1.couId)as couId,
t1.stuId,t1.score
from(select@i:=0,@couIdFlow:=1)as var
crossjoin stuScore as t1
orderby t1.couId asc,t1.score desc)as rankTable on student.stuId=rankTable.stuId
where rankTable.number between2and3;#另一种没什么mysql的思想的#把各自的表拿出外面,再用union all 来往下拼接(select student.*,t1.couId,t1.score from stuScore as t1 leftjoin student on student.stuId=t1.stuId where t1.couId=1orderby score desclimit1,2)unionall(select student.*,t2.couId,t2.score from stuScore as t2 leftjoin student on student.stuId=t2.stuId where t2.couId=2orderby score desclimit1,2)unionall(select student.*,t3.couId,t3.score from stuScore as t3 leftjoin student on student.stuId=t3.stuId where t3.couId=3orderby score desclimit1,2);
#方法就是使用二表联立#这里的group by为什么没有使用select后面的另一张表course.couName?#我只能说再二表联立的时候使用了couId字段#且couName也不是主键,这就不知道从哪区分开来select t1.couId ,course.couName,count(*)as cntAll,sum(casewhen t1.score between85and100then1else0end)/count(*)as'[100-85]',sum(casewhen t1.score between70and85then1else0end)/count(*)as'[85-70]',sum(casewhen t1.score between60and70then1else0end)/count(*)as'[70-60]',sum(casewhen t1.score between0and60then1else0end)/count(*)as'[0-60]'from stuScore as t1
leftjoin course on t1.couId =course.couId
groupby t1.couId;#第二种方法:还不如说是第二种表示,因为其实是一样的select a0.couId,cou.couName,a0.cnt0 as'cntAll',
a1.cnt1/a0.cnt0 as'[100-85]',
a2.cnt2/a0.cnt0 as'[85-70]',
a3.cnt3/a0.cnt0 as'[70-60]',
a4.cnt4/a0.cnt0 as'[60-70]'from course as cou
leftjoin(select couId,count(*)as cnt0
from stuScore
groupby couId
)as a0 on cou.couId=a0.couId
leftjoin(select couId,count(*)as cnt1
from stuScore
where score between85and100groupby couId
)as a1 on a0.couId=a1.couId
leftjoin(select couId,count(*)as cnt2
from stuScore
where score between70and85groupby couId
)as a2 on a0.couId=a2.couId
leftjoin(select couId,count(*)as cnt3
from stuScore
where score between60and70groupby couId
)as a3 on a0.couId=a3.couId
leftjoin(select couId,count(*)as cnt4
from stuScore
where score between0and60groupby couId
)as a4 on a0.couId=a4.couId;#先到这里吧!一坨shit
题24:查询学生平均成绩及其名次
#其实这张表有点不清晰,#究竟没录入stuScore表的成绩是学生缺考=0分#还是说学生不用学这门课#以下是对”不用学“的表示,总分除以参加考试的科目select(@i:=@i+1)as'NO.',
resultTable.stuId,resultTable.stuName,resultTable.avgScore
from(select(@i:=0))as var
crossjoin(select student.stuId,student.stuName,avg(t1.score)as avgScore
from student
leftjoin stuScore as t1 on student.stuId=t1.stuId
groupby stuId
orderbyavg(t1.score)desc)as resultTable;#以下是一种缺考为0分共计入计算的select(@i:=@i+1)as'NO.',
resultTable.stuId,resultTable.stuName,resultTable.avgScore
from(select(@i:=0))as var
crossjoin(select student.stuId,student.stuName,sum(t1.score)/(selectcount(*)from course)as avgScore
from student
leftjoin stuScore as t1 on student.stuId=t1.stuId
groupby stuId
orderbysum(t1.score)/3desc)as resultTable;
题25:查询各科成绩前三名的记录
#赖皮蛇玩法:union all 串一串(select stu.*,t1.score,t1.couId,course.couName from student as stu leftjoin stuScore as t1 on stu.stuId=t1.stuId leftjoin course on course.couId=t1.couId where t1.couId=1orderby t1.score desclimit0,3)unionall(select stu.*,t1.score,t1.couId,course.couName from student as stu leftjoin stuScore as t1 on stu.stuId=t1.stuId leftjoin course on course.couId=t1.couId where t1.couId=2orderby t1.score desclimit0,3)unionall(select stu.*,t1.score,t1.couId,course.couName from student as stu leftjoin stuScore as t1 on stu.stuId=t1.stuId leftjoin course on course.couId=t1.couId where t1.couId=3orderby t1.score desclimit0,3)#第二种方法,从变量排名中筛出来#之前那道题用过了select student.*,hasRank.number,hasRank.couName,hasRank.score
from(select(@i:=casewhen@couIdFlow=result.couId then@i+1else1end)as number,(@couIdFlow:=result.couId)as flow2,result.*from(select@i:=0,@couIdFlow:=1)as var
crossjoin(select t1.stuId,course.couName,t1.score,t1.couId
from stuScore as t1
leftjoin course on t1.couId=course.couId
orderby t1.couId asc,t1.score desc)as result
)as hasRank
leftjoin
student on student.stuId=hasRank.stuId
where hasRank.number between1and3;
题26:查询每门课程被选修的学生数
#实际上这个问题就很奇异了,因为我想了一下,这不是很简单吗?#因为没选某门课的学生再stuScore里面就是没有显示啊select cou.couId,cou.couName,count(t1.couId)as studentNumber
from stuScore as t1
leftjoin course as cou
on cou.couId=t1.couId
groupby t1.couId;
题27:查询出只有两门课程的全部学生的学号和姓名
#突然这么简单,有点不适应select student.stuId,student.stuName
from student
leftjoin stuScore as t1 on t1.stuId=student.stuId
groupby stuId
havingcount(*)=2;
题28:查询男生、女生人数
select student.stuSex,count(*)as sexNumber
from student
groupby stuSex;
题29:查询名字中含有"风"字的学生信息
#太假啦!太假了!select*from student where stuName like'%浩%';
题30:查询同名同性学生名单,并统计同名人数
#用一张表,用分组计数,查询就好#使用group by就要考虑版本默认与否开启group by mole的问题#如果是没开启的,或者关闭掉的,这里使用studen.*就可以了select student.stuName,student.stuSex,count(*)from student
groupby student.stuName,student.stuSex
havingcount(*)>1;#另一种比较人性化的方法:如下select student.stuName,student.stuSex,count(*)as'all',group_concat(stuId)as'stuId'from student
groupby student.stuName,student.stuSex
havingcount(*)>1;#如果要查询学生信息的话是如下#为什么不用left join 或其他的join#这样会把t1和t2一条一条连接起来,查询的时候也是一条一条#这样也就是说,当你用stuId关联起来#在查到某条stuId=2的时候,另一张表并不能用别的stuId滑动#只能是stuId=2#使用cross join 就是因为它的”毫无关系“#只是因为要用到第二张表来做条件判断select t1.*from student as t1
crossjoin student as t2
where t1.stuId!=t2.stuId
and t1.stuName=t2.stuName
and t1.stuSex=t2.stuSex
orderby t1.stuId;
题31:查询1990年出生的学生名单
#如果你在stuDate,学生生日字段使用了varchar类型,那么以下就行select*from student where stuDate like'1990%';#如果使用的是Date类型,那么就要select*from student whereyear(stuDate)='1990';
题32:查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
select t1.couId,avg(t1.score)from stuScore as t1
groupby t1.couId
orderbyavg(t1.score)desc,couId asc;
题33:查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
select student.stuId,student.stuName,avg(t1.score)from student
leftjoin stuScore as t1 on student.stuId=t1.stuId
GROUPBY student.stuId
havingavg(t1.score)>=85;
题34:查询课程名称为"数学",且分数低于60的学生姓名和分数
#方法:总表再筛选select student.*,t2.couName,t1.score
from student
leftjoin stuScore as t1 on t1.stuId=student.stuId
leftjoin course as t2 on t2.couId=t1.couId
where t2.couName='数学'and t1.score<60;#这一种也差不多吧。只是说可能速度会快一点点点点select student.*,t2.couName,t1.score
from student
leftjoin stuScore as t1 on t1.stuId=student.stuId and t1.score<60leftjoin course as t2 on t2.couId=t1.couId
where t2.couName='数学';
题35:查询所有学生的课程及分数情况
#如果是为了符合要求的话,不要求美化的话,以下通过普普通通的表表联立select student.*,t2.couName,t1.score
from student
leftjoin stuScore as t1 on t1.stuId=student.stuId
leftjoin course as t2 on t2.couId=t1.couId;#如果要为了美化的话,即一条记录里面有各课程字段和各分数select student.*,r1.score as'score01',r2.score as'score02',r3.score as'score03'from student
leftjoin(select stuId,score from stuScore where couId=1)as r1 on r1.stuId=student.stuId
leftjoin(select stuId,score from stuScore where couId=2)as r2 on r2.stuId=student.stuId
leftjoin(select stuId,score from stuScore where couId=3)as r3 on r3.stuId=student.stuId;
题36:查询任何一门课程成绩在70分以上的姓名、课程名称和分数
#如果是为了符合要求的话,不要求美化的话,以下通过普普通通的表表联立select student.stuName,cou.couName,t1.score from student leftjoin(select*from stuScore where score>=70)as t1 on student.stuId=t1.stuId leftjoin course as cou on cou.couId=t1.couId;#如果要为了美化的话,即一条记录里面有各课程字段和各分数select student.stuName
,group_concat(couName,score separator ' ; ')as'course and score'from student
innerjoin(select*from stuScore where score>=70)as t1
on student.stuId=t1.stuId innerjoin course as cou
on cou.couId=t1.couId
groupby student.stuName;
题37:查询课程不及格的学生
#可以沿用上面的‘美化’方法select student.stuName
,group_concat(couName,score separator ' ; ')as'course and score'from student
innerjoin(select*from stuScore where score<60)as t1
on student.stuId=t1.stuId innerjoin course as cou
on cou.couId=t1.couId
groupby student.stuName;#也可以使用不美化的方法,就不列举了,改个判断条件就行了。#当当符合题目要求就行的,#使用inner join 是为了某些没选这门课的学生不出现select student.*from student
innerjoin(selectdistinct stuId from stuScore where score<60)as r1 on r1.stuId=student.stuId;
题38:查询课程编号为01且课程成绩在80分以上的学生的学号和姓名
#又突然出现这么简单的题,有点不太适应select student.stuId,student.stuName
from student
innerjoin stuScore as t1 on t1.stuId=student.stuId
where couId=1and score>=80;
题39:求每门课程的学生人数
这道题不就是二十六题吗?【26:查询每门课程被选修的学生数】
#还是写一下吧,但是写一个就好了,不加课程名称:select couId,count(*)from stuScore groupby couId;#加课程名称:select course.couId,course.couName,count(*)from stuScore as t1 leftjoin course on course.couId=t1.couId groupby course.couId;
题40:查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩
#这一道题一看就要三表联立了,张三老师要用teacher表,#张三老师所授课程要用course表#找到成绩和对比要用stuScore表#要拿到学生信息要用student表#方法1:赖皮蛇打法,玩一套多重嵌套,或子父关系输出的,#即某张表需要的某个输入从另一张表得到select student.*,sco.couName,sco.score from student
innerjoin(select stuId,couName,score from stuScore
innerjoin(select couId,couName from course
innerjoin(select teaId from teacher
where teaName='张老师')as tea
on tea.teaId=course.teaId
)as cou on cou.couId=stuScore.couId
orderby stuScore.score desclimit0,1)as sco on sco.stuId=student.stuId;#方法二:,表表联立,总表出来再筛选,简简单单的思想,不玩脑回路select student.*,tea.teaName,cou.couName,t1.score
from student
leftjoin stuScore as t1 on t1.stuId=student.stuId
leftjoin course as cou on cou.couId=t1.couId
leftjoin teacher as tea on tea.teaId=cou.teaId
where tea.teaName='张老师'orderby score desclimit0,1;
题41:查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
#这是一种没有美化的方式,能够符合要求,但是不够美化#这里还是group by里面体现了,按每条记录筛选的可能#当 stuId couId1 couId2 socre# 2 1 2 58# 2 1 3 58#会合并为一条 2 1(couid1)58#看起来couId1 和 couId2 中[1,2]和[1,3]并不属于一组#但是经过cross join 后和筛选后,有多出来一般#而这样的group by 又能够缩少一半,这样就比较无厘头的完成了效果select t1.stuId,t1.couId,t1.score
from stuScore as t1
crossjoin stuScore as t2
where t1.stuId=t2.stuId
and t1.couId!=t2.couId
and t1.score=t2.score
groupby t1.stuId,t1.couId,t1.score;#方法2:偏算法类型,一种依靠聚合函数的#select stuScore.*from stuScore
innerjoin(select t1.stuId,t1.score
from stuScore as t1
groupby t1.stuId,t1.score havingcount(*)>=2)as r1
on stuScore.stuId=r1.stuId and stuScore.score=r1.score;#方法3:#这里是稍微美化的一种,因为配置文件的问题,#在select字段再命名的时候,因为不能再where后面起作用#所以使用了一个一级嵌套来用#方法的思路是“01挥旗方法flag”selectdistinct result.*from(select r1.stuId
,(casewhen a1.score=a2.score or a1.score=a3.score then1else0end)as course01
,(casewhen a1.score=a2.score or a3.score=a2.score then1else0end)as course02
,(casewhen a1.score=a3.score or a3.score=a2.score then1else0end)as course03
,r1.score
from
stuScore as r1
leftjoin(select stuId,score from stuScore where couId=1)as a1 on r1.stuId=a1.stuId
leftjoin(select stuId,score from stuScore where couId=2)as a2 on r1.stuId=a2.stuId
leftjoin(select stuId,score from stuScore where couId=3)as a3 on r1.stuId=a3.stuId
)as result
where result.course01=1or result.course02=1or result.course03=1;#方法4:采用group_concatselect r2.stuId,r2.score
,group_concat(r2.couId orderby r2.couId asc)as'couId'from(select stuScore.*from stuScore
innerjoin(select t1.stuId,t1.score
from stuScore as t1
groupby t1.stuId,t1.score havingcount(*)>=2)as r1
on stuScore.stuId=r1.stuId and stuScore.score=r1.score
)as r2
groupby r2.stuId,r2.score;
题42:查询每门功成绩最好的前两名
#方法一:用union all 无赖打法,如果不要求显示学生名字(select*from stuScore where couId=1orderby score desclimit0,2)unionall(select*from stuScore where couId=2orderby score desclimit0,2)unionall(select*from stuScore where couId=3orderby score desclimit0,2);#要用学生名字?也简单select student.stuId,student.stuName,r1.couId,r1.score from student innerjoin((select*from stuScore where couId=1orderby score desclimit0,2)unionall(select*from stuScore where couId=2orderby score desclimit0,2)unionall(select*from stuScore where couId=3orderby score desclimit0,2))as r1 on student.stuId=r1.stuId;#方法二:用变量(诶,这题好像前面做过了,当复习吧)select r1.*from(select(@i:=casewhen@couIdFlow=t1.couId then@i+1else1end)as number,(@couIdFlow:=t1.couId)as'couId',t1.stuId,t1.score from(select@i:=0,@couIdFlow:=1)as var crossjoin stuScore as t1 orderby t1.couId asc,t1.score desc)as r1 where r1.number between1and2;#还有一位大佬写的方法:很精妙select a.s_id,a.c_id,a.s_score from score a
where(selectCOUNT(1)from score b where b.c_id=a.c_id and b.s_score>=a.s_score)<=2orderby a.c_id
源头:https://www.cnblogs.com/kangxinxin/p/11585935.html
#以前学过点java和C,对数值比较敏感#这里用dayofweek的方法会返回一个数值#西方那边的计日不太一样,是这样子的 周日是1,周一是2,周六是7select student.*from student crossjoin(select dayofweek(curdate())as wekNum1) t1
where stuDate between
date_sub(curdate(),INTERVAL dayofweek(curdate())-2day)and date_add(curdate(),INTERVAL(dayofweek(curdate())-7-1)*(-1)day);#解释一下between里面的数值采用#我们返回的数字为准要回到星期一,即总是需要curdate-2#要走到星期日,即总是需要7-curdate+1,后面发现总是出错,-(-7+curdate-1)
题48:查询下周过生日的学生
#在明白47题的情况下,在判断条件体里面加7不久好咯?#事实也是这样子的select student.*from student
where stuDate between
date_sub(curdate(),INTERVAL dayofweek(curdate())+7-2day)and date_add(curdate(),INTERVAL(dayofweek(curdate())-7-7-1)*(-1)day);
题49:查询本月过生日的学生
#月份方面的计数还是没什么变化,更简单#因为不用担心“周日是哪个周的周日的问题”#一月就是1,十二月就是12select student.*from student
wheremonth(student.stuDate)=month(curdate());##--------------#突然想了一下,用那个“周”的题目是不是也可以算月啊,试一下select student.*from student crossjoin(select dayofweek(curdate())as wekNum1) t1
where stuDate between
date_sub(curdate(),INTERVAL dayofmonth(curdate())-1day)and LAST_DAY(curdate());