跳转至

6. SQL题目练习

为什么你必须写好SQL?

在我们工作中,无论是业务人员,还是开发人员,或是管理者,如今,几乎每个人都必须使用某种形式的数据,因为数据毕竟是信息的呈现,要获取信息必须得依赖数据,而这些数据通常是以电子表格或是数据库的形式存放。        

现状1:从业务人员视角来看,在企业里面,我们当前的现状就是,业务人员想要看哪些数据得依赖开发人员从数据库中提取数据,而这一过程需要漫长的等待,影响工作效率,如果我们懂简单的SQL,自己能从数据库提取数据,那么工作效率就会有大的提升,在同样的岗位中能够脱颖而出       

现状2:从数据分析师视角来看,习SQL几乎成为数分必备的技能,如果这个技能不达标,基本上很难通过面试,而且近几年SQL面试的题目也越来越难,要想通过面试几乎成为数据分析师必须且深度掌握的技能。      

现状3:从数据开发者角度来看,对于数据开发者来讲,典型的像数仓同学,基本天天与SQL打交道,这里其实与数据分析岗位有交叉的部分,对于SQL的掌握不言而喻。

SQL语法很简单,但几乎没几个人写的很好

这里不得不提国内语言的鄙视链,在大多数程序员眼里,他们认为SQL称不上一门语言,因为门槛太低,语法很简单就几个命令就能搞定,不需要专门学,或是成为一种岗位。有这种认识的往往都不是从事数据相关的人员,他们实际工作中使用SQL语言也很简单,就是简单的增删改查,甚至有时候面试问他们分组TOPN的问题都会难倒一大片,而对从事数据开发或数据分析师来讲,分组TOPN问题却很简单,这就是平时工作方向的不同带来的误区。不同的岗位有不同的工作方向和重点,我们不能以语言简单程度来区分岗位的优劣,或有鄙视心里,因为毕竟语言只是一种工具,而程序员最重要的还是逻辑思维能力,如果我拿语法比较简单的语言比如SQL去处理复杂的业务逻辑,其实未必就是一件简单的事情,他背后需要的是数据处理的逻辑思维及业务知识,其实此时SQL仅仅只是个工具。

在国外Data Science面试中,对SQL的考察,其实要求很高,很多公司要求必须熟练掌握SQL相关基础语法,并具备极强的数据处理思维逻辑,很多面试者也在SQL考察环节栽了跟头。在众多求职者中,我们分析其原因,这些求职者并不是不懂SQL语法,而是缺乏数据分析的思维能力,缺乏必要的实战技巧。甚至我们经常跟很多经验丰富数仓开发同学去聊,他们在用SQL解决实际业务问题时,都是这样的处理逻辑,遇到要分析的指标,先分析指标的含义,搞清楚逻辑及需要取数的源表后,就开始像套公式般找各种内置的函数去套,看看哪种函数能帮我解决业务问题,像极了某些语言开发者去寻找API的过程。但作为成熟的开发者来说,我们在处理数据问题或写代码时是这样吗?这里我们先打个问号,留给读者自己体会。倘若我们的业务逻辑稍微复杂些,套用函数或API套不动了怎么办?业务不做了吗?去跟业务撕逼吗?哈哈,我想办法总比困难多。这也就是我们所说的工作了好多年,你发现没几个人会把SQL写的很好,实际上呢?遇到复杂的业务逻辑或面试题也会凉凉。。。。。。当然实在不行了,我们也可以换语言实现嘛,总之办法总比困难多。最后,对于一个成熟的SQLer,不仅仅只是停留在实现业务逻辑的角度,更重要的一点还要从底层执行引擎的角度去理解SQL执行过程,看懂执行计划,并能写出性能较高的SQL。  

SQL题目练习

--创建表student
create table student(
    name varchar(10),
    kecheng varchar(10),
    fengshu int
)

--插入数据到表student中
insert into student values('张三','语文',81);
insert into student values('张三','数学',75);
insert into student values('李四','语文',76);
insert into student values('李四','数学',90);
insert into student values('王五','语文',81);
insert into student values('王五','数学',100);
insert into student values('王五','英语',90);


-- 查询出每门课都大于80分的学生姓名

-- 因为一个学生有多门课程,可能所有课程都大于80分,可能有些课程大于80分,另外一些课程少于80分,也可能所有课程都小于80分。
-- 那么我们要查找出所有大于80分的课程的学生姓名,我们可以反向思考,找出课程小于80分(可以找出有一些课程小于80分,所有课程小于80分的学生)的学生姓名再排除这些学生剩余的就是所有课程都大于80分的学生姓名了。 

select distinct name from student where name not in (select distinct name from student where fengshu<=80);

/* not in */ 
SELECT DISTINCT A.name FROM student A WHERE A.name not in(SELECT Distinct S.name FROM student S WHERE S.score <80);

/* not exists */ 
SELECT DISTINCT A.name From student A  where not exists (SELECT 1 From student S Where  S.score <80 AND S.name =A.name);

SQL案例题

-- 建库
CREATE DATABASE `emp`;

-- 打开库
USE emp;

-- 部门信息表(部门编号,部门名称,位置)
CREATE TABLE `dept`( 
    `deptno` INT(2) NOT NULL, 
    `dname` VARCHAR(14), 
    `loc` VARCHAR(13), 
    CONSTRAINT pk_dept PRIMARY KEY(deptno) 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 员工信息表(员工编号,员工姓名,工作职位,上级领导,入职日期,月薪,津贴,部门编号)
CREATE TABLE `emp` ( 
    `empno` int(4) NOT NULL PRIMARY KEY, 
    `ename` VARCHAR(10), 
    `job` VARCHAR(9), 
    `mgr` int(4), 
    `hiredate` DATE, 
    `sal` float(7,2), 
    `comm` float(7,2), 
    `deptno` int(2), 
    CONSTRAINT fk_deptno FOREIGN KEY(deptno) REFERENCES dept(deptno) 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 薪水等级信息表(等级,最低薪水,最高薪水)
CREATE TABLE `salgrade` ( 
    `grade` int, 
    `losal` int, 
    `hisal` int 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- 数据
INSERT INTO dept VALUES (10,'ACCOUNTING','NEW YORK'); 
INSERT INTO dept VALUES (20,'RESEARCH','DALLAS');
INSERT INTO dept VALUES (30,'SALES','CHICAGO'); 
INSERT INTO dept VALUES (40,'OPERATIONS','BOSTON');
INSERT INTO emp VALUES (7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20); 
INSERT INTO emp VALUES (7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30); 
INSERT INTO emp VALUES (7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30); 
INSERT INTO emp VALUES (7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp VALUES (7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30); 
INSERT INTO emp VALUES (7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30); 
INSERT INTO emp VALUES (7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10); 
INSERT INTO emp VALUES (7788,'SCOTT','ANALYST',7566,'1987-07-13',3000,NULL,20); 
INSERT INTO emp VALUES (7839,'KING','PRESIDENT',NULL,'1981-11-07',5000,NULL,10); 
INSERT INTO emp VALUES(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30); 
INSERT INTO emp VALUES (7876,'ADAMS','CLERK',7788,'1987-07-13',1100,NULL,20); 
INSERT INTO emp VALUES (7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30); 
INSERT INTO emp VALUES (7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20); 
INSERT INTO emp VALUES (7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);
INSERT INTO salgrade VALUES (1,700,1200); 
INSERT INTO salgrade VALUES (2,1201,1400); 
INSERT INTO salgrade VALUES (3,1401,2000); 
INSERT INTO salgrade VALUES (4,2001,3000); 
INSERT INTO salgrade VALUES (5,3001,9999);
-- 1. 列出与"SCOTT"从事相同工作的所有员工及部门名称。

-- 获取SCOTT的工作  
SELECT job FROM emp WHERE ename='SCOTT'

-- 关联部门表,获取部门名称,查出(员工,部门)    
SELECT e.ename, d.dname FROM emp e, dept d WHERE e.job =( SELECT job FROM emp WHERE ename = 'SCOTT' ) AND e.ename<>'SCOTT' AND e.deptno=d.deptno


-- 2. 列出公司各个工资等级雇员的数量、平均工资。
SELECT s.grade,count(*),avg(e.sal) FROM emp e LEFT JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal GROUP BY s.grade ;

-- 3. 列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金、部门名称。
select ename,sal,d.dname,d.deptno from emp e left join dept d on e.deptno = d.deptno where e.sal > (select max(sal) from emp where deptno = 30);

-- 4. 列出在每个部门工作的员工数量、平均工资和平均服务期限。
select count(*),avg(sal),avg(year(now())-year(hiredate)) from emp group by deptno;

-- 5. 列出所有员工的姓名、部门名称和工资。
select e.ename,d.dname,e.sal from emp e left join dept d on d.deptno = e.deptno;

-- 6. 列出所有部门的详细信息和部门人数
select d.*,count(e.ename) from dept d left join emp e on e.deptno = d.deptno group by d.deptno;

-- 7. 列出各种工作的最低工资及从事此工作的雇员姓名。
select t.job ,a.ename , t.minsal from emp a left join (select e.job as job , min(e.sal) as minsal from emp e group by e.job) t on a.job = t.job;

-- 8. 列出各个部门的MANAGER(经理)的最低薪金、姓名、部门名称、部门人数。
select a.mm,c.ename,c.job,b.dname,b.cc from (select d.deptno,min(sal) mm from emp e left join dept d on e.deptno = d.deptno where job = 'MANAGER' group by deptno) a left join (select d.deptno,d.dname,count(*) cc from emp e left join dept d on e.deptno = d.deptno group by d.deptno) b on a.deptno = b.deptno left join emp c on c.sal = a.mm and b.deptno = c.deptno ;

-- 9. 列出所有员工的年工资,所在部门名称,按年薪从低到高排序。
select empno,ename,sal * 12 ,d.dname from emp left join dept d on d.deptno = emp.deptno order by sal * 12 asc;

-- 10. 查出某个员工的上级主管及所在部门名称,并要求出这些主管中的月薪超过3000

-- 11. 求出部门名称中,带"S"字符的部门员工的、工资合计、部门人数。

-- 12. 给任职日期超过30年或者在87年雇佣的雇员加薪,加薪原则:10部门增长10%,20部门增长20%, 30部门增长30%,依次类推。

-- 13. 列出至少有一个员工的所有部门的信息。
select  DISTINCT d.* from dept d join emp e on d.deptno = e.deptno; 

-- 14. 列出月薪比JAMES低的所有员工。
select * from emp where sal < (select sal from emp where ename = 'JAMES')

-- 15. 列出所有员工的姓名以及其直接上级的姓名。
select a.empno,a.ename as 'e_name',b.ename as 'm_name' from emp a left join emp b on a.mgr = b.empno;

-- 16. 列出受雇日期早于其直接上级的所有员工的编号、姓名,部门名称。
-- 17. 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门。
-- 18. 列出所有"CLERK(职员)"的姓名以及部门名称,部门的人数。
-- 19. 列出最低薪金大于1500的各种工作以及从事此工作的全部雇员人数。
-- 20. 列出在部门"SALES"工作的员工的姓名,假定不知道销售部的部门编号。
-- 21. 列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,公司的工资等级。
-- 22. 列出至少有一个员工的所有部门编号、名称,并统计出这些部门的平均工资、最低工资、最高工 资。
-- 23. 列出薪金比“SMITH”或“ALLEN”多的所有员工的编号、姓名、部门名称、其领导姓名。
-- 24. 列出所有员工的编号、姓名及其直接上级的编号、姓名,显示的结果按领导年工资的降序排列。
-- 25. 列出受雇日期早于其直接上级的所有员工的编号、姓名、部门名称、部门位置、部门人数。
-- 26. 列出部门名称和这些部门的员工信息(数量、平均工资),同时列出那些没有员工的部门。
-- 27. 列出所有“CLERK”(办事员)的姓名及其部门名称,部门的人数,工资等级。
-- 28. 列出最低薪金大于1500的各种工作及此从事此工作的全部雇员人数及所在部门名称、位置、平均工 资。
-- 29. 列出在部门“SALES”(销售部)工作的员工的姓名、基本工资、雇佣日期、部门名称,假定不知道 销售部的部门编号。
-- 30. 列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,公司的工资等级。
-- 31. 列出与“SCOTT”从事相同工作的所有员工及部门名称,部门人数。
-- 32. 查询dept表的结构
-- 33. 检索emp表,用is a 这个字符串来连接员工姓名和工种两个字段
-- 34. 检索emp表中有提成的员工姓名、月收入及提成。
-- DDL

-- 学生表
-- Student(SId,Sname,Sage,Ssex)
-- SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别

-- 课程表
-- Course(CId,Cname,TId)
-- CId 课程编号,Cname 课程名称,TId 教师编号

-- 教师表
-- Teacher(TId,Tname)
-- TId 教师编号,Tname 教师姓名

-- 成绩表
-- SC(SId,CId,score)
-- SId 学生编号,CId 课程编号,score 分数

create table Student(sid varchar(10),sname varchar(10),sage datetime,ssex nvarchar(10));  
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');  
insert into Student values('02' , '钱电' , '1990-12-21' , '男');  
insert into Student values('03' , '孙风' , '1990-05-20' , '男');  
insert into Student values('04' , '李云' , '1990-08-06' , '男');  
insert into Student values('05' , '周梅' , '1991-12-01' , '女');  
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');  
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');  
insert into Student values('08' , '王菊' , '1990-01-20' , '女');  
create table Course(cid varchar(10),cname varchar(10),tid varchar(10));  
insert into Course values('01' , '语文' , '02');  
insert into Course values('02' , '数学' , '01');  
insert into Course values('03' , '英语' , '03');  
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 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' , '03' , 98);



-- 1. 查询“01”课程比“02”课程成绩高的所有学生的学号;
select distinct t1.sid as sidfrom   
    (select * from sc where cid='01')t1  
left join   
    (select * from sc where cid='02')t2  
on t1.sid=t2.sid  
where t1.score>t2.score

-- 2. 查询平均成绩大于60分的同学的学号和平均成绩;
select   
    sid  
    ,avg(score)  
from sc  
group by sid  
having avg(score)>60

-- 3. 查询所有同学的学号、姓名、选课数、总成绩
select  
    student.sid as sid  
    ,sname  
    ,count(distinct cid) course_cnt  
    ,sum(score) as total_score  
from student  
left join sc  
on student.sid=sc.sid  
group by sid,sname

-- 4. 查询姓“李”的老师的个数;
select  
    count(distinct tid) as teacher_cnt  
from teacher  
where tname like '李%'

-- 5. 查询没学过“张三”老师课的同学的学号、姓名;
select  
    sid,sname  
from student  
where sid not in   
    (  
        select  
            sc.sid  
        from teacher  
        left join course  
            on teacher.tid=course.tid  
        left join sc  
            on course.cid=sc.cid  
        where teacher.tname='张三'  
    )

-- 6. 查询学过“01”并且也学过编号“02”课程的同学的学号、姓名;
select  
    t.sid as sid  
    ,sname  
from   
    (  
        select  
            sid  
            ,count(if(cid='01',score,null)) as count1  
            ,count(if(cid='02',score,null)) as count2  
        from sc  
        group by sid  
        having count(if(cid='01',score,null))>0 and count(if(cid='02',score,null))>0  
    )t  
left join student  
    on t.sid=student.sid

-- 7. 查询学过“张三”老师所教的课的同学的学号、姓名;
select  
    student.sid  
    ,sname  
from   
    (  
        select  
            distinct cid   
        from course  
        left join teacher   
        on course.tid=teacher.tid  
        where teacher.tname='张三'  
    )course  
left join sc   
    on course.cid=sc.cid  
left join student  
    on sc.sid=student.sid  
group by student.sid,sname

-- 8. 查询课程编号“01”的成绩比课程编号“02”课程低的所有同学的学号、姓名;
select  
    t1.sid,sname  
from   
    (  
        select distinct t1.sid as sid  
        from   
            (select * from sc where cid='01')t1  
        left join   
            (select * from sc where cid='02')t2  
        on t1.sid=t2.sid  
        where t1.score>t2.score  
    )t1  
left join student  
    on t1.sid=student.sid

-- 9. 查询所有课程成绩小于60分的同学的学号、姓名;
select  
    t1.sid,sname  
from   
    (  
        select  
            sid,max(score)  
        from sc  
        group by sid  
        having max(score<60)  
    )t1  
left join student  
    on t1.sid=student.sid

-- 10. 查询没有学全所有课的同学的学号、姓名;
select  
    t1.sid,sname  
from   
    (  
        select  
            count(cid),sid  
        from sc  
        group by sid  
        having count(cid) < (select count(distinct cid) from course)  
    )t1  
left join student  
    on t1.sid=student.sid

-- 11. 查询至少有一门课与学号为“01”的同学所学相同的同学的学号和姓名;
select  
    distinct sc.sid  
from   
    (  
        select  
            cid  
        from sc  
        where sid='01'  
    )t1  
left join sc  
    on t1.cid=sc.cid

-- 12. 查询和"01"号的同学学习的课程完全相同的其他同学的学号和姓名
#注意是和'01'号同学课程完全相同但非学习课程数相同的,这里我用左连接解决这个问题select  
    t1.sid,sname  
from  
    (  
        select  
            sc.sid  
            ,count(distinct sc.cid)  
        from   
            (  
                select  
                    cid  
                from sc  
                where sid='01'  
            )t1 #选出01的同学所学的课程  
        left join sc  
            on t1.cid=sc.cid  
        group by sc.sid  
        having count(distinct sc.cid)= (select count(distinct cid) from sc where sid = '01')  
    )t1  
left join student  
    on t1.sid=student.sid  
where t1.sid!='01'

-- 13. 把“SC”表中“张三”老师教的课的成绩都更改为此课程的平均成绩;
-- 暂跳过update题目


-- 14. 查询没学过"张三"老师讲授的任一门课程的学生姓名
select   
    sname  
from student  
where sid not in  
    (  
        select  
            distinct sid  
        from sc  
        left join course  
            on sc.cid=course.cid  
        left join teacher  
            on course.tid=teacher.tid   
        where tname='张三'  
    )

-- 15. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select  
    t1.sid,sname,avg_score  
from   
    (  
        select  
            sid,count(if(score<60,cid,null)),avg(score) as avg_score  
        from sc  
        group by sid  
        having count(if(score<60,cid,null)) >=2  
    )t1  
left join student  
    on t1.sid=student.sid

-- 16. 检索"01"课程分数小于60,按分数降序排列的学生信息
select   
    sid,if(cid='01',score,100)from sc  
where if(cid='01',score,100)<60  
order by if(cid='01',score,100) desc

-- 17. 按平均成绩从高到低显示所有学生的平均成绩
select sid,avg(score)  
from sc  
group by sid  
order by avg(score) desc

-- 18. 查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率
select  
    sc.cid  
    ,cname  
    ,max(score) as max_score  
    ,min(score) as min_score  
    ,avg(score) as avg_score  
    ,count(if(score>=60,sid,null))/count(sid) as pass_rate  
 from sc   
 left join course  
    on sc.cid=course.cid  
 group by sc.cid

-- 19. 按各科平均成绩从低到高和及格率的百分数从高到低顺序
#这里先按照平均成绩排序,再按照及格百分数排序,  
select   
    cid  
    ,avg(score) as avg_score  
    ,count(if(score>=60,sid,null))/count(sid) as pass_rate  
from sc  
group by cid  
order by avg_score,pass_rate desc

-- 20. 查询学生的总成绩并进行排名
select  
    sid  
    ,sum(score) as sum_score  
from sc  
group by sid  
order by sum_score desc

-- 21. 查询不同老师所教不同课程平均分从高到低显示
select  
    tid  
    ,avg(score) as avg_score  
from course  
left join sc  
    on course.cid=sc.cid  
group by tid  
order by avg_score desc

-- 22. 查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
select  
    sid,rank_num,score,cid  
from  
    (  
        select  
            rank() over(partition by cid order by score desc) as rank_num  
            ,sid  
            ,score  
            ,cid  
        from sc  
    )t  
where rank_num in (2,3)

-- 23. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
select  
    sc.cid  
    ,cname  
    ,count(if(score between 85 and 100,sid,null))/count(sid)  
    ,count(if(score between 70 and 85,sid,null))/count(sid)  
    ,count(if(score between 60 and 70,sid,null))/count(sid)  
    ,count(if(score between 0 and 60,sid,null))/count(sid)  
from sc  
left join course  
    on sc.cid=course.cid  
group by sc.cid,cname

-- 24. 查询学生平均成绩及其名次
select  
    sid  
    ,avg_score  
    ,rank() over (order by avg_score desc)  
from   
    (  
        select  
            sid  
            ,avg(score) as avg_score  
        from sc  
        group by sid  
    )t

-- 25. 查询各科成绩前三名的记录
select  
    sid,cid,rank1from   
    (  
        select  
            cid  
            ,sid  
            ,rank() over(partition by cid order by score desc) as rank1  
        from sc  
    )twhere rank1<=3

-- 26. 查询每门课程被选修的学生数
select  
    count(sid)  
    ,cid  
from sc  
group by cid

-- 27. 查询出只选修了一门课程的全部学生的学号
select  
    sid  
from sc  
group by sid  
having count(cid) =1

-- 28. 查询男生、女生人数
select  
    ssex  
    ,count(distinct sid)  
from student          
group by ssex

-- 29. 查询名字中含有"风"字的学生信息
select  
    sid,sname  
from student  
where sname like '%风%'

-- 30. 查询同名同性学生名单,并统计同名人数
select  
    ssex  
    ,sname  
    ,count(sid)  
from student  
group by ssex,sname  
having count(sid)>=2

-- 31. 查询1990年出生的学生名单(注:Student表中Sage列的类型是datetime)
select  
    sid,sname,sage  
from student  
where year(sage)=1990

-- 32. 查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
select  
    cid,avg(score) as avg_score  
from sc  
group by cid  
order by avg_score,cid desc

-- 33. 查询不及格的课程,并按课程号从大到小排列
select  
    cid,sid,score  
from sc  
where score<60  
order by cid desc,sid

-- 34. 查询课程编号为"01"且课程成绩在60分以上的学生的学号和姓名;
select  
    sid,cid,score  
from sc  
where cid='01' and score>60

-- 35. 查询选修“张三”老师所授课程的学生中,成绩最高的学生姓名及其成绩
select  
    sc.sid,sname,cname,score  
from sc  
left join course  
    style="font-weight: 600;">=course.cid  
left join teacher  
    style="font-weight: 600;">=teacher.tid  
left join student  
    style="font-weight: 600;">=student.sid  
where tname='张三'  
order by score desc  
limit 1;

-- 36. 查询每门功课成绩最好的前两名
select  
    cid,sid,rank1  
from   
    (  
        select  
            cid  
            ,sid  
            ,rank() over(partition by cid order by score desc) as rank1  
        from sc   
    )t  
where rank1 <=2

-- 37. 统计每门课程的学生选修人数(超过5人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
select  
    cid  
    ,count(sid) as cnt  
from sc  
group by cid  
having cnt>=5  
order by count(sid) desc,cid

-- 38. 检索至少选修两门课程的学生学号
select  
    sid  
    ,count(cid)  
from sc  
group by sid  
having count(cid)>=2

-- 39. 查询选修了全部课程的学生信息
select  
    sid  
    ,count(cid)  
from sc  
group by sid  
having count(cid)=(select count(distinct cid) from sc)

-- 40. 查询各学生的年龄
select  
    sid,sname,year(curdate())-year(sage) as sage  
from student

-- 41. 查询本周过生日的学生
select  
    sid,sname,sage  
from student  
where weekofyear(sage)=weekofyear(curdate())

-- 42. 查询下周过生日的学生
select   
    sid,sname,sage  
from student  
where weekofyear(sage) = weekofyear(date_add(curdate(),interval 1 week))

-- 43 查询本月过生日的学生
select  
    sid,sname,sage  
from student  
where month(sage) = month(curdate())

-- 44. 查询下月过生日的学生
select  
    sid,sname,sage  
from student  
where month(date_sub(sage,interval 1 month)) = month(curdate())