mysql查询每门课最高分的_子查询

对于网上经典的SQL笔试题目解答进行整理,过程中参考了网上的两篇文章,下文有链接。

下文中脚本都是基于SQL Server进行编写的。

具体表结及数据可以参考下面这两篇文章。

经典SQL50题,做完这些sql就入门了

Fire:sql经典题目练习zhuanlan.zhihu.com

1.查询" 01 “课程比” 02 "课程成绩高的学生的信息及课程分数
SELECT t3.sid
      ,t3.class1
      ,t3.class2
      ,t4.*
FROM (SELECT t1.sid
            ,t1.score AS class1 
            ,t2.score AS class2
      FROM sc t1 LEFT JOIN sc t2
      ON t1.sid=t2.sid
      WHERE t1.cid='01' AND 
            t2.cid='02' AND 
            t1.score>t2.score
      ) t3
      LEFT JOIN student t4
      ON t3.sid=t4.sid ;
      
2.查询同时存在" 01 “课程和” 02 "课程的情况
SELECT t1.sid
      ,t1.score AS class1
      ,t2.score AS class2
FROM sc t1 LEFT JOIN sc t2
ON t1.sid=t2.sid
WHERE t1.cid='01' AND 
      t2.cid='02' ;

3.查询存在" 01 “课程但可能不存在” 02 "课程的情况(不存在时显示为 NULL )
SELECT t1.sid
      ,t1.cid
      ,t1.score
      ,t2.cid
      ,t2.score
FROM (SELECT sid
            ,cid
            ,score
      FROM sc 
      WHERE cid='01'
      ) t1
      LEFT JOIN 
      (SELECT sid
             ,cid
             ,score
       FROM  sc 
       WHERE cid='02'
       ) t2
ON t1.sid=t2.sid ;

4.查询不存在" 01 “课程但存在” 02 "课程的情况
解法一:FULL OUTER JOIN + NULL判断 
SELECT t2.sid
      ,t2.cid
      ,t2.score
FROM(SELECT sid
           ,cid
           ,score
     FROM sc 
     WHERE cid='01'
    ) t1
    FULL OUTER JOIN 
    (SELECT sid
           ,cid
           ,score
     FROM  sc 
     WHERE cid='02'
    ) t2
    ON t1.sid=t2.sid
WHERE t1.score IS NULL AND 
      t2.score IS NOT NULL ;
解法二:子查询,NOT IN
SELECT *
FROM sc
WHERE sc.sid NOT IN (SELECT sid 
                     FROM sc 
                     WHERE sc.cid='01'
                     )
 AND  sc.cid='02';

5.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
SELECT t1.sid
      ,t2.sname
      ,t1.avg_score
FROM(SELECT sid
           ,AVG(score) AS avg_score
     FROM sc
     GROUP BY sid
     HAVING AVG(score)>=60
     ) t1
     LEFT JOIN 
     student t2
ON  t1.sid=t2.sid
ORDER BY avg_score DESC ;

6.查询在 SC 表存在成绩的学生信息
解法一:
SELECT t1.*
FROM student t1
WHERE EXISTS (SELECT *
              FROM sc t2 
              WHERE t1.sid=t2.sid
              );
解法二:
SELECT t1.*
FROM student t1
WHERE sid IN (SELECT sid 
              FROM sc );

7.查询所有同学的学生编号、学生姓名、选课总数、所有课程的成绩总和
--包含没选课的学生信息,NULL表示
SELECT t1.sid
      ,t1.sname
      ,t2.course_cnt
      ,t2.score_total
FROM (SELECT sid
            ,sname
      FROM student
      ) t1
      LEFT JOIN
      (SELECT sid
             ,COUNT(DISTINCT cid) AS course_cnt
             ,SUM(score)          AS score_total
      FROM sc 
      GROUP BY sid
      ) t2
      ON t1.sid=t2.sid ; 

8.查询「李」姓老师的数量
SELECT COUNT(DISTINCT tid) AS teacher_cnt
FROM teacher
WHERE tname like '李%';

9.查询学过「张三」老师授课的同学的信息
SELECT t1.*
FROM student t1 
     INNER JOIN sc t2
      ON t1.sid=t2.sid
     INNER JOIN course t3
      ON t2.cid=t3.cid
     INNER JOIN teacher t4 
      ON t3.tid=t4.tid
WHERE t4.tname='张三' ;

10.查询没有学全所有课程的同学的信息
解法一:CROSS JOIN + NULL判断
SELECT t3.sid
      ,t3.sname
      ,t3.sage
      ,t3.ssex
FROM(SELECT t1.*
           ,t2.cid
     FROM student t1
     CROSS JOIN course t2
     ) t3
     LEFT JOIN
     (SELECT sid
            ,cid
      FROM sc
     ) t4
     ON t3.sid=t4.sid AND 
        t3.cid=t4.cid
WHERE t4.sid IS NULL AND 
      t4.cid IS NULL
GROUP BY  t3.sid
         ,t3.sname
         ,t3.sage
         ,t3.ssex ; 
解法二:子查询+ NOT IN   
SELECT * 
FROM student t1
WHERE t1.sid NOT IN (SELECT sid 
                     FROM sc t2 
                     GROUP BY sid 
                     HAVING COUNT(t2.cid)>=(SELECT COUNT(cid) 
                                            FROM course
                                            )
                    );
         
11.查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
SELECT  t1.sid
       ,t1.sname
       ,t1.sage
       ,t1.ssex
FROM(SELECT sid
           ,sname
           ,sage
           ,ssex
     FROM student 
     ) t1
     INNER JOIN 
     (SELECT sid 
      FROM sc
      WHERE cid IN (SELECT cid
                    FROM sc 
                    WHERE sid='01'
                    )
        AND sid!='01'
      GROUP BY sid
      ) t2
      ON t1.sid=t2.sid ;

12.查询和" 01 "号的同学学习的课程完全相同的其他同学的信息
SELECT t.*
FROM student t
WHERE sid IN (SELECT sid
              FROM sc
              WHERE cid IN (SELECT cid
                            FROM sc 
                            WHERE sid='01'
                            )
                 AND sid!='01' 
              GROUP BY sid   
              HAVING COUNT(DISTINCT cid)=(SELECT COUNT(DISTINCT cid) FROM sc WHERE sid='01')
              ) ;

13.查询没学过"张三"老师讲授的任一门课程的学生姓名
方法一:嵌套子查询+NOT IN
SELECT sid
      ,sname
FROM student
WHERE sid NOT IN (SELECT sid
                  FROM sc
                  WHERE cid IN (SELECT cid 
                                FROM course 
                                WHERE tid IN (SELECT tid 
                                              FROM teacher 
                                              WHERE tname='张三'
                                              )
                                )
                  ) ;
方法二:NOT EXISTS+内联结
SELECT sid
      ,sname
FROM student t1
WHERE NOT EXISTS (SELECT 0 
                  FROM sc t2 INNER JOIN course t3 
                    ON T2.cid=t3.cid 
                   INNER JOIN teacher t4 
                    ON t3.tid=t4.tid
                  WHERE tname='张三'
                    AND t1.sid=t2.sid
                  );
                           
14.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
SELECT t1.sid
      ,t2.sname
      ,t1.avg_score
FROM  (SELECT sid
             ,AVG(score) AS avg_score
       FROM sc
       WHERE score<60
       GROUP BY sid
       HAVING COUNT(DISTINCT cid)>=2
       ) t1
      INNER JOIN
      (SELECT sid
             ,sname
       FROM student
       ) t2
       ON t1.sid=t2.sid ;

15.检索" 01 "课程分数小于 60,按分数降序排列的学生信息
SELECT t2.*
      ,t1.score
FROM (SELECT sid,score
      FROM sc
      WHERE cid='01' AND 
            score<60
      ) t1
      INNER JOIN student t2
      ON t1.sid=t2.sid
ORDER BY t1.score DESC ;

16.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
SELECT t1.sid
      ,t2.sname
      ,t1.cid
      ,t3.cname
      ,t1.score
      ,t1.avg_score
FROM (SELECT sid
            ,cid
            ,score
            ,AVG(score) OVER (PARTITION BY sid) AS avg_score
      FROM sc
      ) t1
      LEFT JOIN student t2
       ON t1.sid=t2.sid
      LEFT JOIN course t3
       ON t1.cid=t3.cid
ORDER BY t1.avg_score DESC
        ,t1.score DESC ; 
如果不能使用窗口函数,也可以使用自联结匹配平均值

17.查询各科成绩最高分、最低分和平均分,以如下形式显示:
课程ID    课程name    课程人数    最高分    最低分    平均分    及格率    中等率    优良率    优秀率
CId       Cname       number      MAX       MIN       mean      >=60      70-80     80-90    90-100
要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT t1.cid
      ,t2.cname
      ,t1.number
      ,t1.max
      ,t1.min
      ,t1.mean
      ,及格人数*0.1/number AS  及格率
      ,中等人数*0.1/number AS  中等率
      ,优良人数*0.1/number AS  优良率
      ,优秀人数*0.1/number AS  优秀率
FROM(SELECT cid
           ,COUNT(DISTINCT sid)                                       AS number
           ,MAX(score)                                                AS max
           ,MIN(score)                                                AS min
           ,AVG(score)                                                AS mean
           ,SUM(CASE WHEN score BETWEEN 60 AND 100 THEN 1 else 0 end) AS 及格人数
           ,SUM(CASE WHEN score BETWEEN 70 AND 79  THEN 1 else 0 end) AS 中等人数
           ,SUM(CASE WHEN score BETWEEN 80 AND 89  THEN 1 else 0 end) AS 优良人数
           ,SUM(CASE WHEN score BETWEEN 90 AND 100 THEN 1 else 0 end) AS 优秀人数
     FROM sc     
     GROUP BY cid
     ) t1
     LEFT JOIN course t2
      ON t1.cid=t2.cid
ORDER BY t1.number DESC
        ,t1.cid ;

18.按各科成绩进行排序,并显示排名,Score 重复时保留名次空缺(美式排名)
方法一:非窗口函数
SELECT t1.cid
      ,t3.cname
      ,t1.sid
      ,t4.sname
      ,t1.score
      ,COUNT(t2.score)+1 AS USA_rank  --score重复时,不保留空缺名次:count(DISTINCT t2.score)
FROM sc t1 LEFT JOIN sc t2 
 ON t1.cid=t2.cid AND 
    t1.score<t2.score
 LEFT JOIN course t3
  ON t1.cid=t3.cid
 LEFT JOIN student t4
  ON t1.sid=t4.sid
GROUP BY  t1.cid
         ,t3.cname
         ,t1.sid
         ,t4.sname
         ,t1.score
ORDER BY t1.cid
        ,USA_rank ASC ;
方法二:窗口函数
SELECT t1.cid
      ,t2.cname
      ,t1.sid
      ,t3.sname
      ,t1.score
      ,t1.UAS_rank
FROM(SELECT cid
           ,sid
           ,score
           ,RANK() OVER (PARTITION BY cid ORDER BY score DESC) AS UAS_rank
     FROM sc
     ) t1
     LEFT JOIN course t2
      ON t1.cid=t2.cid
     LEFT JOIN student t3
      ON t1.sid=t3.sid ;

19.按各科成绩进行排序,并显示排名,Score 重复时合并名次(中式排名)
SELECT t1.cid
      ,t2.cname
      ,t1.sid
      ,t3.sname
      ,t1.score
      ,t1.CHINA_rank
FROM(SELECT cid
           ,sid
           ,score
           ,DENSE_RANK() OVER (PARTITION BY cid ORDER BY score DESC) AS CHINA_rank
     FROM sc
     ) t1
     LEFT JOIN course t2
      ON t1.cid=t2.cid
     LEFT JOIN student t3
      ON t1.sid=t3.sid ;

20.查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
SELECT t1.sid
      ,t2.sname
      ,SUM(score)                              AS score_total
      ,RANK() OVER (ORDER BY SUM(score) DESC ) AS USA_rank
FROM sc t1
LEFT JOIN student t2
ON t1.sid=t2.sid
GROUP BY t1.sid
        ,t2.sname ;

21.按平均成绩进行排序,显示总排名和各科排名,Score 重复时保留名次空缺
方法一:CROSS JOIN + 分数高低判断
SELECT  t1.sid
       ,t1.sname
       ,t1.sage
       ,t1.ssex
       ,t4.rank_avg
       ,SUM(CASE WHEN t7.cid = '01' THEN t7.rank_course ELSE NULL END) AS rank_01
       ,SUM(CASE WHEN t7.cid = '02' THEN t7.rank_course ELSE NULL END) AS rank_02
       ,SUM(CASE WHEN t7.cid = '03' THEN t7.rank_course ELSE NULL END) AS rank_03
FROM (SELECT sid
            ,sname
            ,sage
            ,ssex
      FROM student
      ) t1
      LEFT JOIN
      (SELECT t2.sid
             ,COUNT(t3.avg_score) AS rank_avg
       FROM (SELECT sid
                   ,AVG(score) AS avg_score
             FROM sc
             GROUP BY sid
             ) t2
             CROSS JOIN
             (SELECT sid
                    ,AVG(score) AS avg_score
              FROM sc
              GROUP BY sid
             ) t3
       WHERE t2.avg_score<=t3.avg_score
       GROUP BY t2.sid
       )t4 
     ON t1.sid = t4.sid
     INNER JOIN 
     (SELECT t5.cid
            ,t5.sid
            ,COUNT(t6.score)+1 AS rank_course
      FROM sc t5 LEFT JOIN sc t6
       ON t5.cid = t6.cid AND 
          t5.score<t6.score
      GROUP BY t5.cid
              ,t5.sid
     ) t7 
     ON t1.sid=t7.sid
GROUP BY  t1.sid
         ,t1.sname
         ,t1.sage
         ,t1.ssex
         ,t4.rank_avg
ORDER BY t4.rank_avg ASC;
方法二:使用窗口函数更简单
SELECT t1.sid
      ,t1.sname
      ,t1.sage
      ,t1.ssex
      ,t3.rank_avg
      ,SUM(CASE WHEN t4.cid = '01' THEN t4.rank_course ELSE NULL END) AS rank_01
      ,SUM(CASE WHEN t4.cid = '02' THEN t4.rank_course ELSE NULL END) AS rank_02
      ,SUM(CASE WHEN t4.cid = '03' THEN t4.rank_course ELSE NULL END) AS rank_03
FROM student t1
     INNER JOIN
     (SELECT sid
             ,RANK() over(ORDER BY avg_score DESC ) AS rank_avg     
     FROM(SELECT sid
                ,AVG(score) AS avg_score
          FROM sc
          GROUP BY sid
          ) t2
      ) t3
      ON t1.sid=t3.sid
      INNER JOIN    
     (SELECT sid
            ,cid
            ,RANK() over (PARTITION BY cid ORDER BY score DESC)  AS rank_course
      FROM sc
      ) t4
      ON t1.sid=t4.sid
GROUP BY  t1.sid
         ,t1.sname
         ,t1.sage
         ,t1.ssex
         ,t3.rank_avg
ORDER BY rank_avg ASC ;      
      
22.统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
SELECT t1.cid
      ,t2.cname
      ,t1.scnt
      ,t1.cnt_0_59
      ,t1.cnt_60_69
      ,t1.cnt_70_84
      ,t1.cnt_85_100
      ,(t1.cnt_0_59   * 0.1) / t1.scnt AS perc_0_59
      ,(t1.cnt_60_69  * 0.1) / t1.scnt AS perc_60_69
      ,(t1.cnt_70_84  * 0.1) / t1.scnt AS perc_70_84
      ,(t1.cnt_85_100 * 0.1) / t1.scnt AS perc_85_10
FROM(SELECT cid
           ,COUNT(DISTINCT sid) AS scnt
           ,SUM(CASE WHEN score BETWEEN 0  AND 59  THEN 1 else 0 end)  AS cnt_0_59
           ,SUM(CASE WHEN score BETWEEN 60 AND 69  THEN 1 else 0 end)  AS cnt_60_69
           ,SUM(CASE WHEN score BETWEEN 70 AND 84  THEN 1 else 0 end)  AS cnt_70_84
           ,SUM(CASE WHEN score BETWEEN 85 AND 100 THEN 1 else 0 end)  AS cnt_85_100
     FROM sc
     GROUP BY cid
     ) t1
     LEFT JOIN course t2
      ON t1.cid=t2.cid ;

23.查询各科成绩前三名的记录
方法一:窗口函数
SELECT cid
      ,sid
      ,score
      ,rn
FROM(SELECT cid
           ,sid
           ,score
           ,DENSE_RANK() OVER (PARTITION BY cid ORDER BY score DESC) AS rn
     FROM sc 
     ) t1 
WHERE rn<=3 ;
方法二:非窗口函数,这个就是前三名转化为若大于此成绩的数量少于3即为前三名。
SELECT *
FROM sc t1  
WHERE  (SELECT COUNT(*) 
        FROM sc t2 
        WHERE t1.cid =t2.cid 
         AND  t1.score <t2.score 
        )<3
ORDER BY t1.cid ASC
        ,t1.score DESC ;

24.查询每门课程被选修的学生数
SELECT cid
      ,COUNT(DISTINCT sid) AS scnt
FROM sc
GROUP BY cid ;

25.查询出只选修两门课程的学生学号和姓名
方法一:子查询
SELECT sid
      ,sname
FROM student t1
WHERE sid IN (SELECT sid
              FROM sc
              GROUP BY sid
              HAVING COUNT(DISTINCT cid)=2
              ) ; 
              
方法二:EXISTS            
SELECT sid
      ,sname
FROM student t1
WHERE EXISTS (SELECT * FROM (SELECT sid
                             FROM sc
                             GROUP BY sid
                             HAVING COUNT(DISTINCT cid)=2
                            ) t2
              WHERE t1.sid=t2.sid
              ) ;
              
26.查询男生、女生人数
SELECT ssex
      ,COUNT(sid)
FROM student
GROUP BY ssex;

27.查询名字中含有「风」字的学生信息
SELECT *
FROM student
WHERE sname like '%风%' ;

28.查询同名学生名单,并统计同名人数
SELECT sname
      ,COUNT(DISTINCT sid) AS scnt
FROM student
GROUP BY sname
HAVING COUNT(DISTINCT sid)>1 ;

39.查询 1990 年出生的学生名单
SELECT *
FROM student
WHERE YEAR(sage)=1990 ;

30.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
SELECT cid
      ,AVG(score) AS avg_score
FROM sc
GROUP BY cid
ORDER BY avg_score DESC 
        ,cid ;
        
31.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
SELECT * 
FROM student
WHERE sid IN (SELECT sid
              FROM sc
              GROUP BY sid
              HAVING AVG(score)>=85
              ) ;

32.查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
SELECT sname
      ,score
FROM (SELECT sid
            ,score
      FROM sc 
      WHERE cid=(SELECT cid 
                 FROM course 
                 WHERE cname='数学')
         AND score<60
      ) t1
      INNER JOIN
      (SELECT sid
             ,sname 
       FROM student
      ) t2
      ON t1.sid=t2.sid ;
      
33.查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
SELECT t1.sid
      ,t1.sname
      ,t2.cid
      ,t2.score
FROM student t1 LEFT JOIN sc t2
ON t1.sid=t2.sid ;

34.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
SELECT t2.sname
      ,t3.cname
      ,t1.score
FROM(SELECT sid,cid,score
     FROM sc
     WHERE sid IN (SELECT sid 
                   FROM sc 
                   WHERE score>70
                   )
     ) t1 
     LEFT JOIN student t2
     ON t1.sid=t2.sid
     LEFT JOIN course t3
     ON t1.cid=t3.cid ;
     
35.查询存在不及格的课程
SELECT t1.cid
      ,t2.cname
FROM sc t1 LEFT JOIN course t2
ON t1.cid = t2.cid
WHERE t1.score<60
GROUP BY t1.cid
        ,t2.cname ;

36.查询课程编号为 01 且课程成绩在 80 分及以上的学生的学号和姓名
SELECT *
FROM student 
WHERE sid IN (SELECT sid
              FROM sc 
              WHERE cid='01' AND 
                    score>=80
              ) ;
              
37.成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
方案一:IN方案
SELECT t1.sid
      ,t2.sname
      ,t2.sage
      ,t2.ssex
      ,t1.cid
      ,t1.score
FROM sc t1
 INNER JOIN student t2
  ON t1.sid=t2.sid
 INNER JOIN course t3
  ON t1.cid=t3.cid
 INNER JOIN teacher t4
  ON t3.tid=t4.tid
WHERE t4.tname='张三' AND 
      t1.score in (SELECT max(t8.score)
                   FROM student t6 
                    INNER JOIN sc t7
                     ON t6.sid=t7.sid
                    INNER JOIN sc t8
                     ON t6.sid=t8.sid
                    INNER JOIN course t9
                     ON t8.cid=t9.cid
                    INNER JOIN teacher t10
                     ON t9.tid=t10.tid
                    WHERE tname='张三'
                    ); 
方案二:EXISTS方案:          
SELECT t1.sid
      ,t2.sname
      ,t2.sage
      ,t2.ssex
      ,t1.cid
      ,t1.score
FROM sc t1
 INNER JOIN student t2
  ON t1.sid=t2.sid
 INNER JOIN course t3
  ON t1.cid=t3.cid
 INNER JOIN teacher t4
  ON t3.tid=t4.tid
WHERE t4.tname='张三' AND 
      NOT EXISTS (SELECT 0
                  FROM student t6 
                    INNER JOIN sc t7
                     ON t6.sid=t7.sid
                    INNER JOIN sc t8
                     ON t6.sid=t8.sid
                    INNER JOIN course t9
                     ON t8.cid=t9.cid
                    INNER JOIN teacher t10
                     ON t9.tid=t10.tid
                  WHERE tname='张三' AND 
                        t1.score<t8.score
                  );  
方案三:窗口函数
SELECT *
FROM(SELECT t2.*
           ,t1.cid
           ,t1.score
           ,DENSE_RANK() over (PARTITION BY cid ORDER BY score DESC) AS rank                      
     FROM sc t1 INNER JOIN student t2
      ON t1.sid=t2.sid
     WHERE cid IN (SELECT t3.cid 
                   FROM course t3 INNER JOIN teacher t4
                    ON t3.tid=t4.tid 
                   WHERE t4.tname='张三')
     ) t5
WHERE rank=1 ;

38.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
SELECT t1.sid
      ,t1.cid
      ,t1.score
FROM sc t1 
     INNER JOIN sc t2
     ON  t1.sid=t2.sid
     AND t1.score=t2.score
     AND t1.cid!=t2.cid
GROUP BY t1.sid
        ,t1.cid
        ,t1.score ;

39.统计每门课程的学生选修人数(超过 5 人的课程才统计)。
SELECT cid
      ,COUNT(DISTINCT sid) AS scnt
FROM sc
GROUP BY cid
HAVING COUNT(DISTINCT sid)>5 ;

40.检索至少选修两门课程的学生学号
SELECT sid
      ,sname
FROM student t1
WHERE sid IN (SELECT sid
              FROM sc
              GROUP BY sid
              HAVING COUNT(DISTINCT cid)>=2
              ) ; 
              
41.查询选修了全部课程的学生信息
方案一:通过比较课程数量计算
SELECT *
FROM student
WHERE sid IN (SELECT sid
              FROM sc 
              GROUP BY sid
              HAVING COUNT(DISTINCT cid)=(SELECT COUNT(DISTINCT cid) 
                                          FROM course
                                          )
              ) ;
方案二:通过嵌套 NOT EXISTS
SELECT *
FROM student t1
WHERE NOT EXISTS (SELECT  * 
                  FROM course t2
                  WHERE NOT EXISTS (SELECT *
                                    FROM sc t3
                                    WHERE t3.sid=t1.sid AND
                                          t3.cid=t2.cid
                                    )
                  ) ;

42.查询各学生的年龄,只按年份来算
SELECT *,DATEDIFF(YEAR,sage,GETDATE())
FROM student ;

43.查询本周过生日的学生
SELECT *
FROM student
WHERE DATEPART(wk,sage)=DATEPART(wk,GETDATE()) ;

44.查询下周过生日的学生
SELECT *
FROM student
WHERE DATEPART(wk,sage)=DATEPART(wk,GETDATE())+1 ;

45.查询本月过生日的学生
SELECT *
FROM student
WHERE MONTH(sage)=MONTH(GETDATE()) ;

46.查询下月过生日的学生
SELECT *
FROM student
WHERE MONTH(sage)=MONTH(GETDATE())+6 ;

PS:为了验证数据,可以将student、sc、course、teacher四张表组合起来放入Excel表格。
SELECT t1.sid
      ,t1.sname
      ,t1.sage
      ,t1.ssex
      ,t2.cid
      ,t3.cname
      ,t3.tid
      ,t4.tname
      ,t2.score
FROM student t1 
     LEFT JOIN sc t2
      ON t1.sid=t2.sid
     LEFT JOIN course t3 
      ON t2.cid=t3.cid 
     LEFT JOIN teacher t4
      ON t3.tid=t4.tid ;