50道经典SQL练习题

MySQL练习

50道经典SQL练习题

数据表介绍
  • 1.学⽣表 Student(SId,Sname,Sage,Ssex)

  • SId 学⽣编号

  • Sname 学⽣姓名

  • Sage 出⽣年⽉

  • Ssex 学⽣性别

  • 2.课程表 Course(CId,Cname,TId)

    • CId 课程编号

    • Cname 课程名称

    • TId 教师编号

  • 3.教师表 Teacher(TId,Tname)

    • TId 教师编号

    • Tname 教师姓名

  • 4.成绩表 SC(SId,CId,score)

    • SId 学⽣编号

    • CId 课程编号

    • score 分数

建表语句
  • 学⽣表 Student

        create table Student(
            SId varchar(10),
            Sname varchar(10),
            Sage datetime,
            Ssex varchar(10)
        ); 
    
  • 课程表 Course

    create table Course(
        CId varchar(10),
        Cname nvarchar(10),
        TId varchar(10)
    );
    
  • 教师表 Teacher

    create table Teacher(
        TId varchar(10),
        Tname varchar(10)
    );
    
  • 成绩表 SC

    create table SC(
        SId varchar(10),
        CId varchar(10),
        score decimal(18,1)
    );
    
插入数据
  • 学⽣表 Student

    -- 学生表 Student
    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' , '⼥'); 
    
  • 课程表 Course

    -- 科⽬表 Course 
    insert into Course values('01' , '语⽂' , '02'); 
    insert into Course values('02' , '数学' , '01'); 
    insert into Course values('03' , '英语' , '03');
    
  • 教师表 Teacher

    -- 教师表 Teacher 
    insert into Teacher values('01' , '张三'); 
    insert into Teacher values('02' , '李四'); 
    insert into Teacher values('03' , '王五'); 
    
  • 成绩表 SC

    -- 成绩表 SC 
    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 tt1.*,tt2.score from
	(select * from Student) tt1
join
    (select t1.SID,t1.score from
    -- 显示SC表的自关联求出符合条件的学生的SID
        (select * from SC) t1
    join
        (select * from SC) t2
    on t1.SID=t2.SID and t1.CID='01' and t2.CID='02' and t1.score>t2.score) tt2
on tt1.SID=tt2.SID;
2.查询同时存在" 01 “课程和” 02 "课程的情况
select tt1.* from
	(select * from Student) tt1
join
    (select t1.SID from
            (select * from SC) t1
        join
            (select * from SC) t2
        on t1.SID=t2.SID and t1.CID='01' and t2.CID='02') tt2
on tt1.SID=tt2.SID;
3.查询存在" 01 “课程但可能不存在” 02 "课程的情况(不存在时显示为 null )
-- 但可能不存在” 02 "课程(不存在时显示为 null )???
select * from
-- 先求出联合表,再查找数据
    (select t1.SID,t1.score as t1_score,t2.score as t2_score from
              (select * from SC) t1
          left join
              (select * from SC) t2
          on t1.SID=t2.SID and t1.CID='01' and t2.CID='02') tt1
where tt1.t2_score is null;

-- 下方正确,上方不对,二者相似却差别很大
select * from
-- 先查找符合的数据,联合后再进行查找
    (select t1.SID,t1.score as t1_score,t2.score as t2_score from
              (select * from SC s1 where s1.CID='01') t1
          left join
              (select * from SC s2 where s2.CID='02') t2
          on t1.SID=t2.SID) tt1
where tt1.t2_score is null;
4.查询不存在" 01 “课程但存在” 02 "课程的情况
select tt1.* from
	(select * from Student) tt1
join   
   (select t1.SID from
    -- 先取出所有没有01课程的学生
        (select * from SC where SID not in (select SID from SC where CID='01')) t1
    join
    -- 再判断其是否有02课程
        (select * from SC where SID not in (select SID from SC where CID='01')) t2
    on t1.SID=t2.SID and t1.CID='02' and t2.CID!='02') tt2
on tt1.SID=tt2.SID;


-- 法二(同第三题)
select * from
-- 先查找符合的数据,联合后再进行查找
    (select t1.SID,t1.score as t1_score,t2.score as t2_score from
              (select * from SC s2 where s2.CID='02') t1
          left join
              (select * from SC s1 where s1.CID='01') t2
          on t1.SID=t2.SID) tt1
where tt1.t2_score is null;

5.查询平均成绩⼤于等于 60 分的同学的学⽣编号和学⽣姓名和平均成绩
-- 注:在外层调用内一层的聚合函数的结果须得为其起别名(avg(score) as avgs)
select t1.SID,t1.sname,t2.avgs from
	(select * from Student) t1 --等同于 Student t1
join
	(select SID,avg(score) as avgs from SC group by SID having avg(score)>=60) t2
on t1.SID=t2.SID;
6.查询在 SC 表存在成绩的学⽣信息
select t1.* from
	(select * from Student) t1
join   
   (select SID from SC group by SID) t2
on t1.SID=t2.SID;
7.查询所有同学的学⽣编号、学⽣姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
select t1.*,t2.count_course,t2.sum_course from
	(select * from Student) t1
left join
-- 注:SUM为列值求和函数,count函数来计算课程总数
	(select SID,count(*) as count_course,SUM(score) as sum_course from SC group by SID ) t2
on t1.SID=t2.SID;
8.查询「李」姓⽼师的数量
--注: 通配符‘%’与‘like’一同使用; %匹配0个或多个
select count(t1.Tname) FROM
-- 取所有李姓老师组成一个组,再用count函数求数量
	(select Tname from Teacher where Tname HAVING Tname LIKE '李%' group by TID) t1;
	
-- 若有同名该如何应对???
-- 解决方案:对CID、Tname一并进行分组
select count(t1.TID) as counts from
	(select TID,Tname from Teacher group by TID,Tname having Tname LIKE '李%') t1;
9.查询学过「张三」⽼师授课的同学的信息
select t1.* from
   (select * from Student) t1
join 
-- 多次查询求出被张三带过的学生的SID
   (select SID from SC where CID=(select CID from Course where TID=(select TID from Teacher where Tname='张		三'))) t2
on t1.SID=t2.SID;
10.查询没有学全所有课程的同学的信息
-- 注:一门课程都没修的学生也无法输出,不够完整,没选课的学生无法输出
select t1.*,t2.count_course from
	(select * from Student) t1
right join
	(select SID,count(*) as count_course from SC group by SID having count(*)<3) t2
on t1.SID=t2.SID;

-- 解决方案:计算出所有学全的学生再过滤
select * from Student where SID not in
	(select SID 
     from SC 
     group by SID 
     having count(*)=3);
11.查询⾄少有⼀⻔课与学号为" 01 "的同学所学相同的同学的信息
-- 注:我已取出所要的SID,无需再次进行关联,只需 where SID in(SID),即可从Student表中取出想要的值
select ttt1.* from
	(select * from Student) ttt1
join
    (select * from
     --法一:使用group by 来实现去重 ; 法二:distinct t2.SID实现去重
     -- 先取出所有符合条件的学生的SID,会有重复值
        (select t2.SID from
         -- 取出所有SID='01'的数据行,与自身比较进行关联再取值
            (select * from SC where SID='01') t1
        join
            (select * from SC) t2
        on t1.SID!=t2.SID and t1.CID=t2.CID) tt1 group by tt1.SID) ttt2
on ttt1.SID=ttt2.SID;

-- 法二:
select * from Student where SID in
    (select 
    SID 
    from SC 
    where CID in (select CID from SC s1 where SID="01") and SID!='01' 
    -- 实现去重
     group by SID);

12.查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息
-- 完全相同如何判别??? 
-- 解决方案:group_concat(CID order by CID)的使用
select * 
from Student  
where SID in 
	(select t1.SID from 
                (select
                SID 
                ,group_concat(CID order by CID) as gc
                from SC
                group by sid) t1
        where t1.gc=(select group_concat(CID order by CID) as gc from SC where SID='01') and t1.SID!='01');
13.查询没学过"张三"⽼师讲授的任⼀⻔课程的学⽣姓名
-- 注:合并的右表返回的SID有两个重复的值,故在最外层查询时使用distinct函数去重,这样就避免了对右侧表进行group by去重的操作
select distinct t1.* from
   (select * from Student) t1
right join 
   (select * from SC where SID not in (select SID from SC where CID='01')) t2
on t1.SID=t2.SID;

--法二:
select * from Student where sid not in (
    -- 计算学过张三老师上的课
	select distinct sid from SC where cid in (
		select 
			t2.cid 
		from 
			(select tid from Teacher where tname='张三' ) t1
		join Course t2
		on t1.tid=t2.tid)
)
14.查询两⻔及其以上不及格课程的同学的学号,姓名及其平均成绩
-- 两⻔及其以上不及格课程: 注意 where 的优先级高于group by
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(*)>=2) t1
join
	Student t2
on t1.SID=t2.SID;

15.检索" 01 "课程分数⼩于 60,按分数降序排列的学⽣信息
-- 最好最后做order by
select t1.* from	
	(select * from Student) t1
join
-- 先找出符合条件的学生SID
	(select SID from SC where CID='01' and score<60 order by score DESC) t2
on t1.SID=t2.SID;
16.按平均成绩从⾼到低显示所有学⽣的所有课程的成绩以及平均成绩
select t1.SID,t2.CID,t1.avg_score,t2.score from
	(select SID,avg(score) as avg_score from SC group by SID) t1
join
	(select SID,CID,score from SC) t2
-- 最外层得到最终结果后,将结果按照成绩平均数降序排序
on t1.SID=t2.SID order by t1.avg_score DESC;
17.查询各科成绩最⾼分、最低分和平均分: 以如下形式显示:课程 ID,课程 name,最⾼分,最低分,平均分,及格率,中等率,优良率,优秀率 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90要求输出课程号和选修⼈数,查询结果按⼈数降序排列,若⼈数相同,按课程号升序排列
-- 查询各科成绩最⾼分、最低分和平均分
select t1.Cname,t2.* from
-- 取出课程名称
	(select * from Course) t1
join
-- 取出最⾼分、最低分和平均分、及格率,中等率,优良率,优秀率
	(select 
        CID
     	,max(score) as max
     	,min(score) as min
     	,avg(score)as avg
     	,count(*) as count
        ,sum(if(score>=60 and score<70 ,1,0))/count(*) as '及格'
        ,sum(if(score<80 and score>=70,1,0))/count(*) as '中等'
        ,sum(if(score<90 and score>=80,1,0))/count(*) as '优良'
        ,sum(if(score<100 and score>=90,1,0))/count(*) as '优秀'
		from SC group by CID) t2
on t1.CID=t2.CID 
-- 查询结果按⼈数降序排列,若⼈数相同,按课程号升序排列
order by t2.count,t2.CID;

18.按各科平均成绩进⾏排序,并显示排名, Score 重复时保留名次空缺
-- 注: Score 重复时保留名次空缺时的处理
-- 只有设定一个i来保证Score 重复时保留名次空缺(即排名有重复且排名不连续)
set @i:=0;
set @last_score:=0.0;
set @j:=0;
select
   *
   ,@j:=@j+1
   ,@last_score
   ,if(@last_score=t1.avg_score,@i:=@i,@i:=@j) as rank
   ,@last_score:=t1.avg_score
from
   (select 
    CID
    ,avg(score) as avg_score
    from SC 
    group by CID
    order by avg_score desc,CID) t1;

19.按各科平均成绩进⾏排序,并显示排名, Score 重复时不保留名次空缺
-- 注: Score 重复时不保留名次空缺时的处理
-- 只有设定一个i来保证Score 重复时不保留名次空缺(即排名虽有重复但排名连续)
set @i:=0;
set @last_score:=0.0;
select
   *
   ,@last_score
   ,if(@last_score=t1.avg_score,@i:=@i,@i:=@i+1) as rank
   ,@last_score:=t1.avg_score
from
   (select 
    CID
    ,avg(score) as avg_score
    from SC 
    group by CID
    order by avg_score desc,CID) t1;

20.查询学⽣的总成绩,并进⾏排名,总分重复时保留名次空缺
-- 同18题
set @i:=0;
set @last_score:=0.0;
set @j:=0;
select
   *
   ,@j:=@j+1
   ,@last_score
   ,if(@last_score=t1.sum_score,@i:=@i,@i:=@j) as rank
   ,@last_score:=t1.sum_score
from
   (select 
    SID
    ,sum(score) as sum_score
    from SC 
    group by SID
    order by sum_score desc,SID) t1;
21.查询学⽣的总成绩,并进⾏排名,总分重复时不保留名次空缺
-- 同19题
set @i:=0;
set @last_score:=0.0;
select
   *
   ,@last_score
   ,if(@last_score=t1.sum_score,@i:=@i,@i:=@i+1) as rank
   ,@last_score:=t1.sum_score
from
   (select 
    SID
    ,sum(score) as sum_score
    from SC 
    group by SID
    order by sum_score desc,SID) t1;
22.统计各科成绩各分数段⼈数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0]及所占百分⽐
-- 注:if的使用
select 
CID
,sum(if(score<60,1,0))/count(*) as '[60-0]'
,sum(if(score<70 and score>=60,1,0))/count(*) as '[70-60]'
,sum(if(score<85 and score>=70,1,0))/count(*) as '[85-70]'
,sum(if(score<100 and score>=85,1,0))/count(*) as '[100-85]'
from SC group by CID
23.查询各科成绩前三名的记录
--- 按照课程号CID分组,每组只取前三个,并将三个表上下联合
select t2.*,t1.Sname from
	(select * from Student) t1
join
        ((select SID,CID,score from SC where CID='01' order by score DESC limit 3)
    union
        (select SID,CID,score from SC where CID='02' order by score DESC limit 3)
    union
        (select SID,CID,score from SC where CID='03' order by score DESC limit 3)) t2
on t1.SID=t2.SID order by CID;
24.查询每⻔课程被选修的学⽣数
select t1.*,t2.counts from
	(select * from Course) t1
join
	(select CID,count(*) as counts from SC group by CID) t2
on t1.CID=t2.CID;

-- coun(*) count(1) count(字段名) 区别
25.查询出只选修两⻔课程的学⽣学号和姓名
select t1.SID,t1.Sname from
	(select * from Student) t1
join
	(select SID,count(*) from SC group by SID having count(*)=2) t2
on t1.SID=t2.SID;

-- 更简洁方式(不用表关联来做)
select 
SID
,Sname 
from Student 
where SID in (select SID from SC group by SID having count(*)=2);

26.查询男⽣、⼥⽣⼈数
select Ssex,count(*) from Student group by Ssex;
27.查询名字中含有「⻛」字的学⽣信息
-- 通配符‘%’匹配0个或多个 ???匹配不出
select * from Student where Sname LIKE '%风%';

-- 乱码,复制编译器中的风字即可匹配到
select * from Student where Sname LIKE '%⻛%';
28.查询同名同性学⽣名单,并统计同名⼈数
-- 想的太复杂!!!
select tttt1.*,tttt2.counts from
-- 显示同名学生的信息
    (select tt1.* from
        (select * from Student) tt1
    right join
     -- 求出所有姓名相同的学生的SID并进行过滤(每种SID只取一个)
        (select DISTINCT t1.SID from
            (select * from Student) t1
        join
            (select * from Student) t2
        on t1.SID!=t2.SID and t1.Sname=t2.Sname) tt2
    on tt1.SID=tt2.SID) tttt1
join
-- 求出每种姓名的总人数
    (select count(*) as counts from
        (select tt1.* from
                        (select * from Student) tt1
                right join
                        (select DISTINCT t1.SID from
                                (select * from Student) t1
                        join
                                (select * from Student) t2
                        on t1.SID!=t2.SID and t1.Sname=t2.Sname) tt2
        on tt1.SID=tt2.SID) ttt1 group by ttt1.Sname) tttt2
 
 -- 法二:
 -- SUBSTR()字符串方法来截取学生的“名”
select t1.name,t1.Ssex,count(*) from
	(select SUBSTR(Sname,2)as name,Ssex from Student) t1
group by t1.name,t1.Ssex;
 
 
29.查询 1990 年出⽣的学⽣名单
-- year()函数的使用
select * from Student where year(Sage)='1990'
30.查询每⻔课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
--法一 平均成绩相同时,按课程编号升序排列---ORDER BY t2.score_avg desc,t1.CID asc
select t1.*,t2.score_avg from
        (select * from Course) t1
    join
        (select avg(score) as score_avg,CID from SC group by CID) t2
on t1.CID=t2.CID 
ORDER BY t2.score_avg desc,t1.CID asc;
-- 法二
select CID,avg(score) from SC group by CID order by avg(score) desc,CID asc
31.查询平均成绩⼤于等于 85 的所有学⽣的学号、姓名和平均成绩
select t1.*,t2.avg_score from
	(select * from Student) t1
join
	(select SID,avg(score) as avg_score from SC group by SID having avg(score)>=85) t2
on t1.SID=t2.SID;
32.查询课程名称为「数学」,且分数低于 60 的学⽣姓名和分数
select t1.Sname,t2.score from
	(select * from Student) t1
join
-- 查找所有符合条件的学生,并返回其SID
	(select * from SC where score<60 and CID=(select CID from Course where Cname='数学')) t2
on t1.SID=t2.SID;
33.查询所有学⽣的课程及分数情况(存在学⽣没成绩,没选课的情况)
select tt1.Sname,tt2.Cname,tt2.score from
	(select * from Student) tt1
-- 没选课的学生也给他输出
left join
    (select t2.SID,t2.score,t1.Cname from
        (select * from Course) t1
    join
        (select * from SC) t2
    on t1.CID=t2.CID) tt2
on tt1.SID=tt2.SID;
34.查询任何⼀⻔课程成绩在 70 分以上的姓名、课程名称和分数
-- 查询任何⼀⻔课程成绩都在 70 分以上的姓名、课程名称和分数
select tt1.Sname,tt2.Cname,tt2.score from
-- 取出所有符合条件的学生的信息
    (select SID,Sname from Student where SID in (select SID from SC group by SID having min(score)>70)) tt1
join
-- 将SC、Course两张表进行关联
    (select t2.SID,t2.score,t1.Cname from
            (select * from Course) t1
        join
            (select * from SC) t2
        on t1.CID=t2.CID) tt2
on tt1.SID=tt2.SID;+
35.查询不及格的课程
-- 查询出所有不及格科目及其对应的学生
select tt1.Sname,tt2.Cname,tt2.score from
	(select * from Student) tt1
join
    (select t2.SID,t1.Cname,t2.score from
        (select * from Course) t1
    join
        (select SID,CID,score from SC where score<60) t2
    on t1.CID=t2.CID) tt2
on tt1.SID=tt2.SID;
36.查询课程编号为 01 且课程成绩在 80 分以上的学⽣的学号和姓名
select t1.SID,t1.Sname from
	(select * from Student) t1
join
	(select SID from SC where CID='01' and score>=80) t2
on t1.SID=t2.SID;
37.求每⻔课程的学⽣⼈数
select t1.Cname,t2.counts from
	(select * from Course) t1
join
	(select CID,count(*) as counts from SC group by CID) t2
on t1.CID=t2.CID;
38.成绩不重复,查询选修「张三」⽼师所授课程的学⽣中,成绩最⾼的学⽣信息及其成绩
-- 与Student表相关联,取出该学生的全部信息
select tt1.*,tt2.score from
	(select * from Student) tt1
join
-- 取出符合条件的学生的SID、score
(select SID,score from SC where CID=(select CID from Course where TID=(select TID from                                                              Teacher where Tname='张三')) and score = (select t1.max from
                                        -- 取出符合条件的最高成绩
                                        (select max(score) as max,CID from SC 
                                            group by CID 
                                            having CID=(select CID from Course where TID=(select TID from                                                                              Teacher where Tname='张三'))) t1)) tt2
on tt1.SID=tt2.SID;
39.成绩有重复的情况下,查询选修「张三」⽼师所授课程的学⽣中,成绩最⾼的学⽣信息及其成绩
-- 重复也可以实现查找
-- 与Student表相关联,取出该学生的全部信息
select tt1.*,tt2.score from
	(select * from Student) tt1
join
-- 取出符合条件的学生的SID、score
(select SID,score from SC where CID=(select CID from Course where TID=(select TID from                                                              Teacher where Tname='张三')) and score = (select t1.max from
                                        -- 取出符合条件的最高成绩
                                        (select max(score) as max,CID from SC 
                                            group by CID 
                                            having CID=(select CID from Course where TID=(select TID from                                                                              Teacher where Tname='张三'))) t1)) tt2
on tt1.SID=tt2.SID;

-- 法二:
select 
	* 
from 
	(
	select 
		tt2.*
	from 
		(select cid,max(score) as max_sco from SC where cid in (
			select t2.cid from 
				(select tid from Teacher where tname='张三') t1
			join Course t2
			on t1.tid=t2.tid)
		group by cid) tt1
	join SC tt2
	on tt1.max_sco=tt2.score and tt1.cid=tt2.cid
	) ttt1
join Student ttt2
on ttt1.sid= ttt2.sid;
40.查询不同课程成绩相同的学⽣的学⽣编号、课程编号、学⽣成绩
-- 可以找出数据但是会有重复的行???
select t1.SID,t1.CID,t1.score from
	(select * from SC) t1
join 
	(select * from SC) t2
on t1.SID!=t2.SID and t1.CID!=t2.CID and t1.score=t2.score;

-- 解决重复值 使用group by 分组
select * from 
	(select t1.SID,t1.CID,t1.score from
		(select * from SC) t1
	join 
		(select * from SC) t2
	on t1.SID!=t2.SID and t1.CID!=t2.CID and t1.score=t2.score) tt1
group by tt1.SID,tt1.CID,tt1.score;
41.查询每⻔课程成绩最好的前两名
-- 分别将这几门课程进行排序,取每个分组中的前两名并合并
select * from
(select * from SC where CID='01' order by score desc limit 2) t1
union
(select * from SC where CID='02' order by score desc limit 2)
union
(select * from SC where CID='03' order by score desc limit 2);
42.统计每⻔课程的学⽣选修⼈数(超过 5 ⼈的课程才统计)。
-- 与Course表相关联取课程名
select t1.CID,t1.Cname,t2.counts from
	(select * from Course) t1
join
-- 找出符合条件的课程的CID
	(select CID,count(*) as counts from SC group by CID having count(*)>5) t2
on t1.CID=t2.CID;

43.检索⾄少选修两⻔课程的学⽣学号
select SID,count(*) from SC group by SID having count(*)>=2;
44.查询选修了全部课程的学⽣信息
select t1.* from
	(select * from Student) t1
join
	(select SID,count(*) from SC group by SID having count(*)=3) t2
on t1.SID=t2.SID;
45.查询各学⽣的年龄,只按年份来算
-- 取现在的年份与学生的出生年份相减
-- CURDATE()、year()函数的使用
select Sname,year(CURDATE())-year(Sage) as Student_age from Student;
46.按照出⽣⽇期来算,当前⽉⽇ < 出⽣年⽉的⽉⽇则,年龄减⼀
--当前⽉⽇ < 出⽣年⽉的⽉⽇???
--多种情况,下面只取了一种 month(Sage)>month(CURDATE()) and day(Sage)>day((CURDATE())
select 
Sname 
,if (month(Sage)>month(CURDATE()) and day(Sage)>day((CURDATE()),year(CURDATE())-year(Sage)-1,year(CURDATE())-year(Sage)) as Student_age
from Student;
     
-- 正确解法
-- 使用DATE_FORMAT()求解
select 
	Sname
    ,if(DATE_FORMAT(CURDATE(),"%m%d")<DATE_FORMAT(Sage,"%m%d")
    	,year(CURDATE())-year(Sage)-1
        ,year(CURDATE())-year(Sage)
    )
from Student;
47.查询本周过⽣⽇的学⽣
-- 法一:通过这是一年中的第几个星期数并不能确定
-- weekofyear()函数返回一个日期的年份中的周数???是否可以这样求解;这样无法求解该问题,无法用周数来计算
select 
Sname
from Student where weekofyear(Sage)=weekofyear(CURDATE());

-- 法二:
-- DATE_FORMAT()
-- WEEKDAY函数返回一个日期的工作日索引值,即星期一为0,星期二为1,星期日为6。
-- WEEKDAY(date)
-- 这是周一
select date_add(now(), INTERVAL -WEEKDAY(NOW()) DAY)
-- 这是周日
select date_add(now(), INTERVAL -WEEKDAY(NOW())+6 DAY)


select 
	*
	,if(DATE_FORMAT(date_add(now(), INTERVAL -WEEKDAY(NOW()) DAY),"%m%d")<=DATE_FORMAT(Sage,"%m%d") 
         and DATE_FORMAT(date_add(now(), INTERVAL -WEEKDAY(NOW())+6 DAY),"%m%d")>=DATE_FORMAT(Sage,"%m%d")
        -- 做标记:返回1则表示过生日,返回0 则表示不过生日
        ,1
         ,0
  )
from Student;

48.查询下周过⽣⽇的学⽣
-- weekofyear()函数返回一个日期的年份中的周数???是否可以这样求解;不能这样求解
select 
Sname
from Student where weekofyear(Sage)=weekofyear(CURDATE())+1;

-- 正确求解
-- 上一题的基础上再加一个星期即可
select 
	*
	,if(DATE_FORMAT(date_add(now(), INTERVAL -WEEKDAY(NOW())+7 DAY),"%m%d")<=DATE_FORMAT(Sage,"%m%d") 
         and DATE_FORMAT(date_add(now(), INTERVAL -WEEKDAY(NOW())+13 DAY),"%m%d")>=DATE_FORMAT(Sage,"%m%d")
        -- 做标记:返回1则表示过生日,返回0 则表示不过生日
        ,1
         ,0
  )
from Student;

49.查询本⽉过⽣⽇的学⽣
-- 只取月份
select 
Sname
from Student where month(Sage)=month(CURDATE());
50.查询下⽉过⽣⽇的学⽣
--法一: 将月份+1 ;若月份为12月???该如何应对
select 
Sname
from Student where month(Sage)=month(CURDATE())+1;

--法二: DATE_ADD(date,INTERVAL expr type)
--date 参数是合法的日期表达式。expr 参数是您希望添加的时间间隔。type 参数可以是:year month day
select *,DATE_ADD(CURDATE(),INTERVAL 1 month) from Student;
SQL是高级的非过程化编程语言,是沟通数据库服务器和客户端的重要工具,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以,具有完全不同底层结构的不同数据库系统,可以使用相同的SQL语言作为数据输入与管理的SQL接口。 它以记录集合作为操作对象,所有SQL语句接受集合作为输入,返回集合作为输出,这种集合特性允许一条SQL语句的输出作为另一条SQL语句的输入,所以SQL语句可以嵌套,这使它具有极大的灵活性和强大的功能,在多数情况下,在其他语言中需要一大段程序实现的功能只需要一个SQL语句就可以达到目的,这也意味着用SQL语言可以写出非常复杂的语句。    结构化查询语言(Structured Query Language)最早是IBM的圣约瑟研究实验室为其关系数据库管理系统SYSTEM R开发的一种查询语言,它的前身是SQUARE语言。SQL语言结构简洁,功能强大,简单易学,所以自从IBM公司1981年推出以来,SQL语言得到了广泛的应用。如今无论是像Oracle、Sybase、DB2、Informix、SQL Server这些大型的数据库管理系统,还是像Visual Foxpro、PowerBuilder这些PC上常用的数据库开发系统,都支持SQL语言作为查询语言。    美国国家标准局(ANSI)与国际标准化组织(ISO)已经制定了SQL标准。ANSI是一个美国工业和商业集团组织,负责开发美国的商务和通讯标准。ANSI同时也是ISO和International Electrotechnical Commission(IEC)的成员之一。ANSI 发布与国际标准组织相应的美国标准。1992年,ISO和IEC发布了SQL国际标准,称为SQL-92。ANSI随之发布的相应标准是ANSI SQL-92。ANSI SQL-92有时被称为ANSI SQL。尽管不同的关系数据库使用的SQL版本有一些差异,但大多数都遵循 ANSI SQL 标准。SQL Server使用ANSI SQL-92的扩展集,称为T-SQL,其遵循ANSI制定的 SQL-92标准。    SQL语言包含4个部分:    数据定义语言(DDL),例如:CREATE、DROP、ALTER等语句。    数据操作语言(DML),例如:INSERT(插入)、UPDATE(修改)、DELETE(删除)语句。    数据查询语言(DQL),例如:SELECT语句。    数据控制语言(DCL),例如:GRANT、REVOKE、COMMIT、ROLLBACK等语句。    SQL语言包括三种主要程序设计语言类别的语句:数据定义语言(DDL),数据操作语言(DML)及数据控制语言(DCL)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值