50道SQL题笔记
where A.sid is null 不可以 a.sid =null
where a.sid not in 一个只含有列的数据库
distinct 是要核对所有选中列的
是date_add()不是add_date()
curdate返回日期
now()返回日期加时间
timestampdiff需要三个参数,先减完,后返回对应的year, month,week的
datediff针对天,只需要两个参数
除了集合函数,还要选中其他列时,要注意行数是否相同
1 select s.* from student s 2 right join (select sid from sc group by sid) a 3 on a.sid = s.sid;
1 select * from Student where S# in (select distinct S# from SC) 2 --3. 查询在 SC 表存在成绩的学生信息
没想出来4
1 select B.S#,B.Sname,A.选课总数,A.总成绩 from 2 (select S#,COUNT(C#)选课总数,sum(score)总成绩 from SC group by S#)A 3 right join Student B on A.S#=B.S# 4 --4. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为null)
1 select sid ,sname, count(cid), sum(score) from 2 (select s.sid, s.sname, sc.score, sc.cid from student s left join sc on s.sid=sc.sid )a 3 group by sid; 4 -- 我的版本,先把成绩表和学生表join然后在分组 5 -- 他的版本,先把从成绩表中提取出总选课数和总分,然后与学生表join
第5题
1 select COUNT(*)李姓老师数量 from Teacher where Tname like '李%' 2 --5.查询「李」姓老师的数量
第6题
1 select * from student 2 where sid in (select sid from sc 3 where cid in (select cid from course 4 where tid=(select tid from teacher 5 where tname ='张三'))) 6 7 -- 老师表里找到tid,课程表里找到cid,成绩表里找到sid,学生表里找到sname
第7题
1 select * from student where 2 sid in( select sid from(select sid, count(cid)c from sc group by sid )tmp where c<>3);
--我的版本
1 select * from Student where sid in(select sid from SC group by sid having COUNT(cid)<3);
--人家的版本
差别在having上
having的优先级低于group低于where
(select from )后面不加 重命名吗?
第8题
1 select * from student 2 where sid in 3 (select distinct sid from sc where cid in(select cid from sc where sid='01'))
和他的版本一样,根据01同学的cid求出所有选这些课同学的sid,然后distinct
第9题
1 select * from student where sid in 2 (select sid from sc where cid in (select cid from sc where sid ='01') group by sid having count(*)=3);
--又有where又有having,反正having在where之后
第10题
1 select sname from student where 2 sid not in 3 (select sid from sc where cid in 4 (select cid from course where tid in 5 (select tid from teacher where tname='张三')));
group by 算是什么操作呢?
第11题
1 select s.sid, s.sname ,AVG(a.score)平均成绩 from student s right join 2 (select * from sc where score<60)a on s.sid=a.sid 3 group by a.sid having count(a.cid)>=2;
--我的版本,先把成绩低于60的sc record与 student结合,再按sid分组,选择数据大于等于2的组,输出
1 select s.sid, s.sname ,a.平均成绩 from student s right join 2 (select sid, avg(score)平均成绩 from sc where score<60 group by sid having count(cid)>=2)a 3 on s.sid=a.sid;
--他的版本,在sc中选出有大于等于两门成绩不合格的数据,求出平均分,然后再结合,优点是结合时的数量小
group by 是要和 aggregate function结合的,不管是select 里还是having里
第12题
1 select sid, score from sc where cid ='01'and score<60 order by score desc;
第13题
1 select a.sid ,sc.score,sc.cid, a.平均成绩 2 from(select sid, avg(score)平均成绩 from sc group by sid)a 3 left join sc on sc.sid =a.sid 4 order by a.平均成绩 desc;
第14题
语法:
1 sum(case when then 1 else 0 end) 2 case 3 when XXX then XXX 4 when XXX then XXX 5 else XXX 6 7 end
eg:
1 update employee 2 set e_wage = 3 case 4 when job_level = '1' then e_wage*1.97 5 when job_level = '2' then e_wage*1.07 6 when job_level = '3' then e_wage*1.06 7 else e_wage*1.05 8 end
1 select sid, cid,sum(case when score>70 and score<80 then 1 else 0 end) 中等, count(sid)选课人数 from sc group by cid order by count(*)desc, sc.cid asc;
第15题
语法:Rank函数
1 RANK() OVER ( 2 [PARTITION BY partition_expression, ... ] 3 ORDER BY sort_expression [ASC | DESC], ... 4 )
1 select * , rank() over (order by score desc)排名 from sc; 2 select * , dense_rank() over (order by score desc)排名 from sc; 3 4 select * , dense_rank() over (partition by cid order by score desc)排名 from sc;
第21题
1 select sum(case when ssex='男' then 1 else 0 end)男生人数, sum(case when ssex='女'then 1 else 0 end)女生人数 from student;
--正解
2 select Ssex,COUNT(Ssex)人数 from Student group by Ssex;
第22题
1 select * from student where sname like '%风%';
第23题
1 select sname 姓名 , count(*)人数 from student group by sname having count(*)>1;
第24题
1 select * from student where sage like '1990%';
第25题
1 select cid, 平均成绩 from( select cid, avg(score)平均成绩 from sc group by cid) a order by 平均成绩 desc, cid asc;
第26题
1 select a.sid, a.sname, b.平均成绩 from student a 2 left join(select sid, avg(score)平均成绩 from sc group by sid)b on a.sid=b.sid 3 where b.平均成绩>=85;
第27题
1 select a.sname, b.score from student a right join 2 (select sid, score from sc where cid=(select cid from course where cname='数学') and score<60 )b on a.sid=b.sid;
第28题
1 select ab.sid, ab.sname, ab.cid, ab.score ,c.cname from 2 (select a.sid, a.sname, b.cid, b.score from student a left join sc b on a.sid=b.sid)ab 3 left join course c on ab.cid = c.cid 4 order by sid;
第29题
1 select * 2 from(select b.sname, a.sid, a.cid , a.score from (select sid, cid, score from sc where score>70)a 3 left join student b on a.sid=b.sid)ab 4 left join(select cid, cname from course)c on ab.cid=c.cid; 5 --不如直接合并,然后再选出列,这样写太啰嗦了
第30题
1 select * from sc from sc where score<60;
第31题
1 select sid, sname from student where sid in (select sid from sc where cid='01'and score>80);
第32题
1 select cid, count(sid) from sc group by cid;
第33题
1 select a.sid, max(a.score), b.* from (select sid, cid, score from sc where cid in 2 (select cid from course where tid= 3 (select tid from teacher where tname='张三')))a left join student b 4 on a.sid=b.sid
第34题
1 select * from( 2 select a.score, b.* , dense_rank()over(order by score desc)排名 3 from(select sid, cid, score from sc where cid in 4 (select cid from course where tid= 5 (select tid from teacher where tname='张三')))a 6 left join student b on a.sid=b.sid)abc 7 where 排名=1;
第35题
注意和 36解 2 的区别
1 select * from sc t1 where exists(select * from sc t2 where t1.sid=t2.sid and t1.score=t2.score and t1.cid!=t2.cid);
exits的实现是用loop的,外表的每个记录相当于i,内表的每个记录相当于j,如果有true就返回
如果外表有n行,内标有m行,那么n*m次只要有true就可以返回
第36题
查询每门功成绩最好的前两名
1 select cid, sid, score from 2 (select sid,cid,dense_rank()over(partition by cid order by score desc)排名 ,score from sc)a 3 where 排名<3;
1 select * 2 from sc as t1 3 where (select count(*) from sc as t2 where t1.CId=t2.CId and t2.score >t1.score)<2 4 ORDER BY t1.CId
不同于exit,where里面套一个表,他会选出满足条件的所有内表的记录,然后再结合count
第37题
1 select cid , count(sid) 选修人数 from sc group by cid having count(sid)>5;
第38题
1 select sid from sc group by sid having count(cid)>1;
第39题
1 select sid from sc group by sid having count(cid)=3;
第40题
datediff针对天
TIMESTAMPDIFF函数,有参数设置,可以精确到天(DAY)、小时(HOUR),分钟(MINUTE)和秒(SECOND),使用起来比datediff函数更加灵活。对于比较的两个时间,时间小的放在前面,时间大的放在后面。
1 select sid, sname, 2019-year(sage)年龄 from student; 2 select S#,datediff(yy,Sage,GETDATE())年龄 from Student
特殊数据类型的访问
第41题
按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一(周岁), 第40题是直接按年减的
1 select *, timestampdiff(year, sage, now())年龄 from student;
第42题
1 select * from student where week(sage)=week(curdate());
第43题
1 select * from student where week(sage)=week(date_add(curdate(),interval 1 week));
第44题
1 select * from student where month(sage)=month(now());
第45题
查询下个月过生日的
1 select * from student where month(sage)=month(date_add(curdate(),interval 1 month))