MySQL查詢語句的50道練習(2019.09.26進階版)

表名和字段

–1.學生表 
Student(s_id,s_name,s_birth,s_sex) –學生編號,學生姓名, 出生年月,學生性別 
–2.課程表 
Course(c_id,c_name,t_id) – –課程編號, 課程名稱, 教師編號 
–3.教師表 
Teacher(t_id,t_name) –教師編號,教師姓名 
–4.成績表 
Score(s_id,c_id,s_score) –學生編號,課程編號,分數mysql

 

#建表
#學生表
drop table if exists student;
CREATE TABLE if not exists `student`(
    `s_id` VARCHAR(20),
    `s_name` VARCHAR(20) NOT NULL DEFAULT '',
    `s_birth` VARCHAR(20) NOT NULL DEFAULT '',
    `s_sex` VARCHAR(10) NOT NULL DEFAULT '',
    PRIMARY KEY(`s_id`)
);
#課程表
drop table if exists course;
CREATE TABLE if not exists `course`(
    `c_id`  VARCHAR(20),
    `c_name` VARCHAR(20) NOT NULL DEFAULT '',
    `t_id` VARCHAR(20) NOT NULL,
    PRIMARY KEY(`c_id`)
);
#教師表
drop table if exists teacher;
CREATE TABLE if not exists `teacher`(
    `t_id` VARCHAR(20),
    `t_name` VARCHAR(20) NOT NULL DEFAULT '',
    PRIMARY KEY(`t_id`)
);
#成績表
drop table if exists score;
CREATE TABLE if not exists `score`(
    `s_id` VARCHAR(20),
    `c_id`  VARCHAR(20),
    `s_score` INT(3),
    PRIMARY KEY(`s_id`,`c_id`)
);
#插入學生表測試數據
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' , '女');
#課程表測試數據
insert into course values('01' , '語文' , '02');
insert into course values('02' , '數學' , '01');
insert into course values('03' , '英語' , '03');
   
#教師表測試數據
insert into teacher values('01' , '張三');
insert into teacher values('02' , '李四');
insert into teacher values('03' , '王五');
   
#成績表測試數據
insert into score values('01' , '01' , 80);
insert into score values('01' , '02' , 90);
insert into score values('01' , '03' , 99);
insert into score values('02' , '01' , 70);
insert into score values('02' , '02' , 60);
insert into score values('02' , '03' , 80);
insert into score values('03' , '01' , 80);
insert into score values('03' , '02' , 80);
insert into score values('03' , '03' , 80);
insert into score values('04' , '01' , 50);
insert into score values('04' , '02' , 30);
insert into score values('04' , '03' , 20);
insert into score values('05' , '01' , 76);
insert into score values('05' , '02' , 87);
insert into score values('06' , '01' , 31);
insert into score values('06' , '03' , 34);
insert into score values('07' , '02' , 89);
insert into score values('07' , '03' , 98);

  

 

練習題和sql語句

 
-- 一、查詢"01"課程比"02"課程成績高的學生的信息及課程分數
select  a.* ,b.s_score  as  01_score,c.s_score  as  02_score  from
     student a
     join  score b  on  a.s_id=b.s_id  and  b.c_id= '01'
     left  join  score c  on  a.s_id=c.s_id  and  c.c_id= '02'  or  c.c_id =  NULL  where  b.s_score>c.s_score
  
  
-- 二、查詢"01"課程比"02"課程成績低的學生的信息及課程分數
  
select  a.* ,b.s_score  as  01_score,c.s_score  as  02_score  from
     student a  left  join  score b  on  a.s_id=b.s_id  and  b.c_id= '01'  or  b.c_id= NULL
      join  score c  on  a.s_id=c.s_id  and  c.c_id= '02'  where  b.s_score<c.s_score
  
  
-- 三、查詢平均成績大於等於60分的同窗的學生編號和學生姓名和平均成績
select  b.s_id,b.s_name,ROUND( AVG (a.s_score),2)  as  avg_score  from
     student b
     join  score a  on  b.s_id = a.s_id
     GROUP  BY  b.s_id,b.s_name  HAVING  ROUND( AVG (a.s_score),2)>=60;
  
  
-- 四、查詢平均成績小於60分的同窗的學生編號和學生姓名和平均成績
         -- (包括有成績的和無成績的)
  
select  b.s_id,b.s_name,ROUND( AVG (a.s_score),2)  as  avg_score  from
     student b
     left  join  score a  on  b.s_id = a.s_id
     GROUP  BY  b.s_id,b.s_name  HAVING  ROUND( AVG (a.s_score),2)<60
     union
select  a.s_id,a.s_name,0  as  avg_score  from
     student a
     where  a.s_id  not  in  (
                 select  distinct  s_id  from  score);
  
  
-- 五、查詢全部同窗的學生編號、學生姓名、選課總數、全部課程的總成績
select  a.s_id,a.s_name, count (b.c_id)  as  sum_course, sum (b.s_score)  as  sum_score  from
     student a
     left  join  score b  on  a.s_id=b.s_id
     GROUP  BY  a.s_id,a.s_name;
  
  
-- 六、查詢"李"姓老師的數量
select  count (t_id)  from  teacher  where  t_name  like  '李%' ;
  
-- 七、查詢學過"張三"老師授課的同窗的信息
select  a.*  from
     student a
     join  score b  on  a.s_id=b.s_id  where  b.c_id  in (
         select  c_id  from  course  where  t_id =(
             select  t_id  from  teacher  where  t_name =  '張三' ));
  
-- 八、查詢沒學過"張三"老師授課的同窗的信息
select  from
     student c
     where  c.s_id  not  in (
         select  a.s_id  from  student a  join  score b  on  a.s_id=b.s_id  where  b.c_id  in (
             select  c_id  from  course  where  t_id =(
                 select  t_id  from  teacher  where  t_name =  '張三' )));
-- 九、查詢學過編號爲"01"而且也學過編號爲"02"的課程的同窗的信息
  
select  a.*  from
     student a,score b,score c
     where  a.s_id = b.s_id   and  a.s_id = c.s_id  and  b.c_id= '01'  and  c.c_id= '02' ;
  
-- 十、查詢學過編號爲"01"可是沒有學過編號爲"02"的課程的同窗的信息
  
select  a.*  from
     student a
     where  a.s_id  in  ( select  s_id  from  score  where  c_id= '01'  and  a.s_id  not  in ( select  s_id  from  score  where  c_id= '02' )
-- 十一、查詢沒有學全全部課程的同窗的信息
select  s.*  from
     student s  where  s.s_id  in (
         select  s_id  from  score  where  s_id  not  in (
             select  a.s_id  from  score a
                 join  score b  on  a.s_id = b.s_id  and  b.c_id= '02'
                 join  score c  on  a.s_id = c.s_id  and  c.c_id= '03'
             where  a.c_id= '01' ))
-- 十二、查詢至少有一門課與學號爲"01"的同窗所學相同的同窗的信息
select  from  student  where  s_id  in (
     select  distinct  a.s_id  from  score a  where  a.c_id  in ( select  a.c_id  from  score a  where  a.s_id= '01' )
     );
  
-- 1三、查詢和"01"號的同窗學習的課程徹底相同的其餘同窗的信息
  
select  a.*  from  student a  where  a.s_id  in (
     select  distinct  s_id  from  score  where  s_id!= '01'  and  c_id  in ( select  c_id  from  score  where  s_id= '01' )
     group  by  s_id
     having  count (1)=( select  count (1)  from  score  where  s_id= '01' ));
-- 1四、查詢沒學過"張三"老師講授的任一門課程的學生姓名
select  a.s_name  from  student a  where  a.s_id  not  in  (
     select  s_id  from  score  where  c_id =
                 ( select  c_id  from  course  where  t_id =(
                     select  t_id  from  teacher  where  t_name =  '張三' ))
                 group  by  s_id);
  
-- 1五、查詢兩門及其以上不及格課程的同窗的學號,姓名及其平均成績
select  a.s_id,a.s_name,ROUND( AVG (b.s_score))  from
     student a
     left  join  score b  on  a.s_id = b.s_id
     where  a.s_id  in (
             select  s_id  from  score  where  s_score<60  GROUP  BY   s_id  having  count (1)>=2)
     GROUP  BY  a.s_id,a.s_name
  
-- 1六、檢索"01"課程分數小於60,按分數降序排列的學生信息
select  a.*,b.c_id,b.s_score  from
     student a,score b
     where  a.s_id = b.s_id  and  b.c_id= '01'  and  b.s_score<60  ORDER  BY  b.s_score  DESC ;
  
-- 1七、按平均成績從高到低顯示全部學生的全部課程的成績以及平均成績
select  a.s_id,( select  s_score  from  score  where  s_id=a.s_id  and  c_id= '01' as  語文,
                 ( select  s_score  from  score  where  s_id=a.s_id  and  c_id= '02' as  數學,
                 ( select  s_score  from  score  where  s_id=a.s_id  and  c_id= '03' as  英語,
             round( avg (s_score),2)  as  平均分  from  score a   GROUP  BY  a.s_id  ORDER  BY  平均分  DESC ;
  
-- 18.查詢各科成績最高分、最低分和平均分:以以下形式顯示:課程ID,課程name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率
--及格爲>=60,中等爲:70-80,優良爲:80-90,優秀爲:>=90
select  a.c_id,b.c_name, MAX (s_score), MIN (s_score),ROUND( AVG (s_score),2),
     ROUND(100*( SUM ( case  when  a.s_score>=60  then  else  end )/ SUM ( case  when  a.s_score  then  else  end )),2)  as  及格率,
     ROUND(100*( SUM ( case  when  a.s_score>=70  and  a.s_score<=80  then  else  end )/ SUM ( case  when  a.s_score  then  else  end )),2)  as  中等率,
     ROUND(100*( SUM ( case  when  a.s_score>=80  and  a.s_score<=90  then  else  end )/ SUM ( case  when  a.s_score  then  else  end )),2)  as  優良率,
     ROUND(100*( SUM ( case  when  a.s_score>=90  then  else  end )/ SUM ( case  when  a.s_score  then  else  end )),2)  as  優秀率
     from  score a  left  join  course b  on  a.c_id = b.c_id  GROUP  BY  a.c_id,b.c_name
-- 1九、按各科成績進行排序,並顯示排名(實現不徹底)
-- mysql沒有rank函數
     select  a.s_id,a.c_id,
         @i:=@i +1  as  i保留排名,
         @k:=( case  when  @score=a.s_score  then  @k  else  @i  end as  rank不保留排名,
         @score:=a.s_score  as  score
     from  (
         select  s_id,c_id,s_score  from  score  WHERE  c_id= '01'  GROUP  BY  s_id,c_id,s_score  ORDER  BY  s_score  DESC
)a,( select  @k:=0,@i:=0,@score:=0)s
     union
     select  a.s_id,a.c_id,
         @i:=@i +1  as  i,
         @k:=( case  when  @score=a.s_score  then  @k  else  @i  end as  rank,
         @score:=a.s_score  as  score
     from  (
         select  s_id,c_id,s_score  from  score  WHERE  c_id= '02'  GROUP  BY  s_id,c_id,s_score  ORDER  BY  s_score  DESC
)a,( select  @k:=0,@i:=0,@score:=0)s
     union
     select  a.s_id,a.c_id,
         @i:=@i +1  as  i,
         @k:=( case  when  @score=a.s_score  then  @k  else  @i  end as  rank,
         @score:=a.s_score  as  score
     from  (
         select  s_id,c_id,s_score  from  score  WHERE  c_id= '03'  GROUP  BY  s_id,c_id,s_score  ORDER  BY  s_score  DESC
)a,( select  @k:=0,@i:=0,@score:=0)s
-- 20、查詢學生的總成績並進行排名
select  a.s_id,
     @i:=@i+1  as  i,
     @k:=( case  when  @score=a.sum_score  then  @k  else  @i  end as  rank,
     @score:=a.sum_score  as  score
from  ( select  s_id, SUM (s_score)  as  sum_score  from  score  GROUP  BY  s_id  ORDER  BY  sum_score  DESC )a,
     ( select  @k:=0,@i:=0,@score:=0)s
-- 2一、查詢不一樣老師所教不一樣課程平均分從高到低顯示
     select  a.t_id,c.t_name,a.c_id,ROUND( avg (s_score),2)  as  avg_score  from  course a
         left  join  score b  on  a.c_id=b.c_id
         left  join  teacher c  on  a.t_id=c.t_id
         GROUP  BY  a.c_id,a.t_id,c.t_name  ORDER  BY  avg_score  DESC ;
-- 2二、查詢全部課程的成績第2名到第3名的學生信息及該課程成績
  
             select  d.*,c.排名,c.s_score,c.c_id  from  (
                 select  a.s_id,a.s_score,a.c_id,@i:=@i+1  as  排名  from  score a,( select  @i:=0)s  where  a.c_id= '01'   
             )c
             left  join  student d  on  c.s_id=d.s_id
             where  排名  BETWEEN  AND  3
             UNION
             select  d.*,c.排名,c.s_score,c.c_id  from  (
                 select  a.s_id,a.s_score,a.c_id,@j:=@j+1  as  排名  from  score a,( select  @j:=0)s  where  a.c_id= '02'   
             )c
             left  join  student d  on  c.s_id=d.s_id
             where  排名  BETWEEN  AND  3
             UNION
             select  d.*,c.排名,c.s_score,c.c_id  from  (
                 select  a.s_id,a.s_score,a.c_id,@k:=@k+1  as  排名  from  score a,( select  @k:=0)s  where  a.c_id= '03'   
             )c
             left  join  student d  on  c.s_id=d.s_id
             where  排名  BETWEEN  AND  3;
  
  
-- 2三、統計各科成績各分數段人數:課程編號,課程名稱,[100-85],[85-70],[70-60],[0-60]及所佔百分比
  
  
         select  distinct  f.c_name,a.c_id,b.`85-100`,b.百分比,c.`70-85`,c.百分比,d.`60-70`,d.百分比,e.`0-60`,e.百分比  from  score a
                 left  join  ( select  c_id, SUM ( case  when  s_score >85  and  s_score <=100  then  else  end as  `85-100`,
                                             ROUND(100*( SUM ( case  when  s_score >85  and  s_score <=100  then  else  end )/ count (*)),2)  as  百分比
                                 from  score  GROUP  BY  c_id)b  on  a.c_id=b.c_id
                 left  join  ( select  c_id, SUM ( case  when  s_score >70  and  s_score <=85  then  else  end as  `70-85`,
                                             ROUND(100*( SUM ( case  when  s_score >70  and  s_score <=85  then  else  end )/ count (*)),2)  as  百分比
                                 from  score  GROUP  BY  c_id)c  on  a.c_id=c.c_id
                 left  join  ( select  c_id, SUM ( case  when  s_score >60  and  s_score <=70  then  else  end as  `60-70`,
                                             ROUND(100*( SUM ( case  when  s_score >60  and  s_score <=70  then  else  end )/ count (*)),2)  as  百分比
                                 from  score  GROUP  BY  c_id)d  on  a.c_id=d.c_id
                 left  join  ( select  c_id, SUM ( case  when  s_score >=0  and  s_score <=60  then  else  end as  `0-60`,
                                             ROUND(100*( SUM ( case  when  s_score >=0  and  s_score <=60  then  else  end )/ count (*)),2)  as  百分比
                                 from  score  GROUP  BY  c_id)e  on  a.c_id=e.c_id
                 left  join  course f  on  a.c_id = f.c_id
-- 2四、查詢學平生均成績及其名次
         select  a.s_id,
                 @i:=@i+1  as  '不保留空缺排名' ,
                 @k:=( case  when  @avg_score=a.avg_s  then  @k  else  @i  end as  '保留空缺排名' ,
                 @avg_score:=avg_s  as  '平均分'
         from  ( select  s_id,ROUND( AVG (s_score),2)  as  avg_s  from  score  GROUP  BY  s_id)a,( select  @avg_score:=0,@i:=0,@k:=0)b;
-- 2五、查詢各科成績前三名的記錄
             -- 1.選出b表比a表成績大的全部組
             -- 2.選出比當前id成績大的 小於三個的
         select  a.s_id,a.c_id,a.s_score  from  score a
             left  join  score b  on  a.c_id = b.c_id  and  a.s_score<b.s_score
             group  by  a.s_id,a.c_id,a.s_score  HAVING  COUNT (b.s_id)<3
             ORDER  BY  a.c_id,a.s_score  DESC
  
-- 2六、查詢每門課程被選修的學生數
  
         select  c_id, count (s_id)  from  score a  GROUP  BY  c_id
  
-- 2七、查詢出只有兩門課程的所有學生的學號和姓名
         select  s_id,s_name  from  student  where  s_id  in (
                 select  s_id  from  score  GROUP  BY  s_id  HAVING  COUNT (c_id)=2);
  
-- 2八、查詢男生、女生人數
         select  s_sex, COUNT (s_sex)  as  人數   from  student  GROUP  BY  s_sex
  
-- 2九、查詢名字中含有"風"字的學生信息
  
         select  from  student  where  s_name  like  '%風%' ;
  
-- 30、查詢同名同性學生名單,並統計同名人數
  
         select  a.s_name,a.s_sex, count (*)  from  student a   JOIN
                     student b  on  a.s_id !=b.s_id  and  a.s_name = b.s_name  and  a.s_sex = b.s_sex
         GROUP  BY  a.s_name,a.s_sex
  
  
  
-- 3一、查詢1990年出生的學生名單
  
         select  s_name  from  student  where  s_birth  like  '1990%'
  
-- 3二、查詢每門課程的平均成績,結果按平均成績降序排列,平均成績相同時,按課程編號升序排列
  
     select  c_id,ROUND( AVG (s_score),2)  as  avg_score  from  score  GROUP  BY  c_id  ORDER  BY  avg_score  DESC ,c_id  ASC
  
-- 3三、查詢平均成績大於等於85的全部學生的學號、姓名和平均成績
  
     select  a.s_id,b.s_name,ROUND( avg (a.s_score),2)  as  avg_score  from  score a
         left  join  student b  on  a.s_id=b.s_id  GROUP  BY  s_id  HAVING  avg_score>=85
  
-- 3四、查詢課程名稱爲"數學",且分數低於60的學生姓名和分數
  
         select  a.s_name,b.s_score  from  score b  LEFT  JOIN  student a  on  a.s_id=b.s_id  where  b.c_id=(
                     select  c_id  from  course  where  c_name = '數學' and  b.s_score<60
  
-- 3五、查詢全部學生的課程及分數狀況;
  
  
         select  a.s_id,a.s_name,
                     SUM ( case  c.c_name  when  '語文'  then  b.s_score  else  end as  '語文' ,
                     SUM ( case  c.c_name  when  '數學'  then  b.s_score  else  end as  '數學' ,
                     SUM ( case  c.c_name  when  '英語'  then  b.s_score  else  end as  '英語' ,
                     SUM (b.s_score)  as   '總分'
         from  student a  left  join  score b  on  a.s_id = b.s_id
         left  join  course c  on  b.c_id = c.c_id
         GROUP  BY  a.s_id,a.s_name
  
  
  -- 3六、查詢任何一門課程成績在70分以上的姓名、課程名稱和分數;
             select  a.s_name,b.c_name,c.s_score  from  course b  left  join  score c  on  b.c_id = c.c_id
                 left  join  student a  on  a.s_id=c.s_id  where  c.s_score>=70
  
  
  
-- 3七、查詢不及格的課程
         select  a.s_id,a.c_id,b.c_name,a.s_score  from  score a  left  join  course b  on  a.c_id = b.c_id
             where  a.s_score<60
  
--3八、查詢課程編號爲01且課程成績在80分以上的學生的學號和姓名;
         select  a.s_id,b.s_name  from  score a  LEFT  JOIN  student b  on  a.s_id = b.s_id
             where  a.c_id =  '01'  and  a.s_score>80
  
-- 3九、求每門課程的學生人數
         select  count (*)  from  score  GROUP  BY  c_id;
  
-- 40、查詢選修"張三"老師所授課程的學生中,成績最高的學生信息及其成績
  
  
         -- 查詢老師id  
         select  c_id  from  course c,teacher d  where  c.t_id=d.t_id  and  d.t_name= '張三'
         -- 查詢最高分(可能有相同分數)
         select  MAX (s_score)  from  score  where  c_id= '02'
         -- 查詢信息
         select  a.*,b.s_score,b.c_id,c.c_name  from  student a
             LEFT  JOIN  score b  on  a.s_id = b.s_id
             LEFT  JOIN  course c  on  b.c_id=c.c_id
             where  b.c_id =( select  c_id  from  course c,teacher d  where  c.t_id=d.t_id  and  d.t_name= '張三' )
             and  b.s_score  in  ( select  MAX (s_score)  from  score  where  c_id= '02' )
-- 4一、查詢不一樣課程成績相同的學生的學生編號、課程編號、學生成績
     select  DISTINCT  b.s_id,b.c_id,b.s_score  from  score a,score b  where  a.c_id != b.c_id  and  a.s_score = b.s_score
-- 4二、查詢每門功成績最好的前兩名
         -- 牛逼的寫法
     select  a.s_id,a.c_id,a.s_score  from  score a
         where  ( select  COUNT (1)  from  score b  where  b.c_id=a.c_id  and  b.s_score>=a.s_score)<=2  ORDER  BY  a.c_id
-- 4三、統計每門課程的學生選修人數(超過5人的課程才統計)。要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列 
         select  c_id, count (*)  as  total  from  score  GROUP  BY  c_id  HAVING  total>5  ORDER  BY  total,c_id  ASC
-- 4四、檢索至少選修兩門課程的學生學號
         select  s_id, count (*)  as  sel  from  score  GROUP  BY  s_id  HAVING  sel>=2
-- 4五、查詢選修了所有課程的學生信息
         select  from  student  where  s_id  in (       
             select  s_id  from  score  GROUP  BY  s_id  HAVING  count (*)=( select  count (*)  from  course))
--4六、查詢各學生的年齡
     -- 按照出生日期來算,當前月日 < 出生年月的月日則,年齡減一
     select  s_birth,(DATE_FORMAT(NOW(), '%Y' )-DATE_FORMAT(s_birth, '%Y' ) -
                 ( case  when  DATE_FORMAT(NOW(), '%m%d' )>DATE_FORMAT(s_birth, '%m%d' then  else  end ))  as  age
         from  student;
  
  
-- 4七、查詢本週過生日的學生
     select  from  student  where  WEEK(DATE_FORMAT(NOW(), '%Y%m%d' ))=WEEK(s_birth)
     select  from  student  where  YEARWEEK(s_birth)=YEARWEEK(DATE_FORMAT(NOW(), '%Y%m%d' ))
  
     select  WEEK(DATE_FORMAT(NOW(), '%Y%m%d' ))
  
-- 4八、查詢下週過生日的學生
     select  from  student  where  WEEK(DATE_FORMAT(NOW(), '%Y%m%d' ))+1 =WEEK(s_birth)
  
-- 4九、查詢本月過生日的學生
  
     select  from  student  where  MONTH (DATE_FORMAT(NOW(), '%Y%m%d' )) = MONTH (s_birth)
  
-- 50、查詢下月過生日的學生
     select  from  student  where  MONTH (DATE_FORMAT(NOW(), '%Y%m%d' ))+1 = MONTH (s_birth)
相關文章
相關標籤/搜索