1. 程式人生 > >Mysql必練50題及常用方法彙總:從入門到精通

Mysql必練50題及常用方法彙總:從入門到精通

參考原文https://blog.csdn.net/fashion2014/article/details/78826299
答案全部改進並親測有效
–建表
–學生表

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)
) ;

–課程表

create table course(
  c_id varchar (20),
  c_name varchar (20)not null default '',
  t_id varchar (20)not null default '',
  primary key( c_id)
);

–教師表

create table teacher(
  t_id varchar (20),
  t_name varchar (20)not null default '',
  primary key (t_id)
);

–成績表

create table 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);

答案:
– 1、查詢"01"課程比"02"課程成績高的學生的資訊及課程分數

select student.*,a.s_score as 01_score,b.s_score as 02_score
from student
join score a on student.s_id=a.s_id and a.c_id='01'
left join score b on student.s_id=b.s_id and b.c_id='02' or b.c_id=null
where  a.s_score>b.s_score;

– 2、查詢"01"課程比"02"課程成績低的學生的資訊及課程分數

select student.*,a.s_score as 01_score,b.s_score as 02_score
from student
join score a on student.s_id=a.s_id and a.c_id='01' or a.c_id=null
left join score b on student.s_id=b.s_id and b.c_id='02'
where a.s_score<b.s_score;

– 3、查詢平均成績大於等於60分的同學的學生編號和學生姓名和平均成績

select  student.s_id,student.s_name,tmp.avg_score from student
join (
select score.s_id,round(avg(score.s_score),1)as avg_score from score group by s_id)as tmp
on tmp.avg_score>=60
where student.s_id=tmp.s_id;

–答案2

select  student.s_id,student.s_name,round(avg (score.s_score),1) as avg_score from student
join score on student.s_id=score.s_id
group by score.s_id
having avg (score.s_score)>=60;

– 4、查詢平均成績小於60分的同學的學生編號和學生姓名和平均成績
– (包括有成績的和無成績的)

select  student.s_id,student.s_name,tmp.avg_score from student
join (
select score.s_id,round(avg(score.s_score),1)as avg_score from score group by s_id)as tmp
on tmp.avg_score < 60
where student.s_id=tmp.s_id
union
select  s_id,s_name,0 as avg_score from student
where s_id not in
    (select distinct s_id from score);

–答案2

select  student.s_id,student.s_name,round(avg (score.s_score),1) as avg_score from student
join score on student.s_id=score.s_id
group by score.s_id
having avg (score.s_score) < 60
union
select  s_id,s_name,0 as avg_score from student
where s_id not in
    (select distinct s_id from score);

– 5、查詢所有同學的學生編號、學生姓名、選課總數、所有課程的總成績

select student.s_id,student.s_name,(count(score.c_id) )as total_count,sum(score.s_score)as total_score
from student
left join score on student.s_id=score.s_id
group by score.s_id;

– 6、查詢"李"姓老師的數量

select t_name,count(1) from teacher where t_name like '李%';

– 7、查詢學過"張三"老師授課的同學的資訊

select * from student
    join score on student.s_id =score.s_id where score.c_id in (
        select course.c_id from course
            where course.t_id in (
        select teacher.t_id from teacher
            where teacher.t_name='張三'
        )
);

–答案2

select student.* from student
join score on student.s_id =score.s_id
join  course on course.c_id=score.c_id
join  teacher on course.t_id=teacher.t_id and t_name='張三';

– 8、查詢沒學過"張三"老師授課的同學的資訊

select * from student
   where s_id not in (
      select score.s_id from score where score.c_id  in (
      select course.c_id from course where course.t_id   = (
      select teacher.t_id from teacher where teacher.t_name='張三' ))
);

–答案2

select student.* from student
left join (select s_id from score
      join  course on course.c_id=score.c_id
      join  teacher on course.t_id=teacher.t_id and t_name='張三')tmp
on  student.s_id =tmp.s_id
where tmp.s_id is null;

– 9、查詢學過編號為"01"並且也學過編號為"02"的課程的同學的資訊

select * from student
   where s_id in (
      select s_id from score where c_id =1 )
   and s_id in (
      select s_id from score where c_id =2
);

– 10、查詢學過編號為"01"但是沒有學過編號為"02"的課程的同學的資訊

select * from student
   where s_id in (
      select s_id from score where c_id =1 )
   and s_id not in (
      select s_id from score where c_id =2
);

–答案2

select student.* from student
join (select s_id from score where c_id =1 )tmp1
    on student.s_id=tmp1.s_id
left join (select s_id from score where c_id =2 )tmp2
    on student.s_id =tmp2.s_id
where tmp2.s_id is null;

– 11、查詢沒有學全所有課程的同學的資訊

select * from student
   where s_id in (
      select s_id
        from score
          group by s_id
            having count(c_id)=(
               select count(1) from course)
);

– 12、查詢至少有一門課與學號為"01"的同學所學相同的同學的資訊

select * from student
  where s_id<>01 and s_id in (
    select s_id from score  where c_id in (
      select c_id from score
        where score.s_id=01)
    group by s_id
);

– 13、查詢和"01"號的同學學習的課程完全相同的其他同學的資訊

select student.*,tmp.course_id from
  (select s_id ,group_concat(c_id) course_id
      from score group by s_id  having s_id<>1 and course_id =(
        select group_concat(c_id) course_id2
            from score  where s_id=1))tmp
  join student on student.s_id=tmp.s_id;

– 14、查詢沒學過"張三"老師講授的任一門課程的學生姓名

select * from student where s_id not in (
  select s_id from score
  join (
      select c_id from course where t_id in (
        select t_id from teacher where t_name='張三')
  )tmp
  on score.c_id=tmp.c_id);

–答案2

select student.* from student
  left join (select s_id from score
          join (select c_id from course join  teacher on course.t_id=teacher.t_id and t_name='張三')tmp2
          on score.c_id=tmp2.c_id )tmp
  on student.s_id = tmp.s_id
  where tmp.s_id is null;

– 15、查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績

select student.s_id,student.s_name,tmp.avg_score from student
left join (
    select s_id,round(AVG (score.s_score)) avg_score
      from score group by s_id)tmp
      on tmp.s_id=student.s_id
where student.s_id in (
    select s_id from score
      where s_score<60
        group by score.s_id having count(s_id)>1
);

– 16、檢索"01"課程分數小於60,按分數降序排列的學生資訊

select student.*,s_score from student,score
where student.s_id=score.s_id and s_score<60 and c_id='01'
order by s_score desc;

– 17、按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績

select 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 s_id order by '平均分' desc;

–答案2

select a.s_id,tmp1.s_score as chinese,tmp2.s_score as math,tmp3.s_score as english,
    round(avg (a.s_score),2) as avgScore
from score a
left join (select s_id,s_score  from score s1 where  c_id='01')tmp1 on  tmp1.s_id=a.s_id
left join (select s_id,s_score  from score s2 where  c_id='02')tmp2 on  tmp2.s_id=a.s_id
left join (select s_id,s_score  from score s3 where  c_id='03')tmp3 on  tmp3.s_id=a.s_id
group by a.s_id,tmp1.s_score,tmp2.s_score,tmp3.s_score order by avgScore desc;

– 18.查詢各科成績最高分、最低分和平均分:以如下形式顯示:課程ID,課程name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率
–及格為>=60,中等為:70-80,優良為:80-90,優秀為:>=90

select score.c_id as '課程ID',course.c_name as '課程name',max(s_score) as '最高分',min(s_score)as '最低分',
    round(avg(s_score),2) '平均分',
    round(sum(case when s_score>=60 then 1 else 0 end)/sum(case when s_score then 1 else 0 end),2)'及格率',
    round(sum(case when s_score>=70 and s_score<80 then 1 else 0 end)/sum(case when s_score then 1 else 0 end),2)'中等率',
    round(sum(case when s_score>=80 and s_score<90 then 1 else 0 end)/sum(case when s_score then 1 else 0 end),2)'優良率',
    round(sum(case when s_score>=90 then 1 else 0 end)/(SUM(case when s_score then 1 else 0 end)),2)'優秀率'
from score left join course on score.c_id=course.c_id
group by score.c_id;

–答案2

select course.c_id,course.c_name,tmp.maxScore,tmp.minScore,tmp.avgScore,tmp.passRate,tmp.moderate,tmp.goodRate,tmp.excellentRates from course
join(select c_id,max(s_score) as maxScore,min(s_score)as minScore,
    round(avg(s_score),2) avgScore,
    round(sum(case when s_score>=60 then 1 else 0 end)/count(c_id),2)passRate,
    round(sum(case when s_score>=60 and s_score<70 then 1 else 0 end)/count(c_id),2) moderate,
    round(sum(case when s_score>=70 and s_score<80 then 1 else 0 end)/count(c_id),2) goodRate,
    round(sum(case when s_score>=80 and s_score<90 then 1 else 0 end)/count(c_id),2) excellentRates
from score group by c_id)tmp on tmp.c_id=course.c_id;

– 19、按各科成績進行排序,並顯示排名(實現不完全)
– mysql沒有rank函式
–方法1

(select * from
  (select s1.s_id,s1.c_id,s1.s_score,
      (select count(distinct sc.s_score) from score sc
          where sc.s_score>=s1.s_score and sc.c_id='01') 'rank不保留排名'
from score s1 where s1.c_id='01'order by s1.s_score desc) t1 )
union (select * from
  (select s1.s_id,s1.c_id,s1.s_score,
      (select count(distinct sc.s_score) from score sc
          where sc.s_score>=s1.s_score and sc.c_id='02') 'rank不保留排名'
from score s1 where s1.c_id='02' order by s1.s_score desc) t2 )
union (select * from
  (select s1.s_id,s1.c_id,s1.s_score,
      (select count(distinct sc.s_score) from score sc
          where sc.s_score>=s1.s_score and sc.c_id='03') 'rank不保留排名'
from score s1 where s1.c_id='03' order by s1.s_score desc) t3 )

–方法2

(select a.s_id,a.c_id,@i:[email protected]+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 * from score where c_id='01' GROUP BY s_id,c_id,s_score order by s_score desc )a,
(select @i:=0,@k:=0,@score:=0)b)
union
(select a.s_id,a.c_id,@m:[email protected]+1 as i保留排名,
      @k:=(case when @score=a.s_score then @k else @m end) as rank不保留排名,
      @score:=a.s_score as score
from(select * from score where c_id='02' GROUP BY s_id,c_id,s_score order by s_score desc )a,
(select @m:=0,@k:=0,@score:=0)b)
union
(select a.s_id,a.c_id,@x:[email protected]+1 as i保留排名,
      @k:=(case when @score=a.s_score then @k else @x end) as rank不保留排名,
      @score:=a.s_score as score
from(select * from score where c_id='03' GROUP BY s_id,c_id,s_score order by s_score desc )a,
(select @x:=0,@k:=0,@score:=0)b);

– 20、查詢學生的總成績並進行排名

select score.s_id,s_name,sum(s_score) sumscore
  from score ,student
    where score.s_id=student.s_id
    group by score.s_id order by sumscore desc;

– 21、查詢不同老師所教不同課程平均分從高到低顯示
–方法1

select tmp.c_id,t_id,avgscore as '平均分' from(
    (select distinct c_id ,(round((select avg(s_score) from score
        where c_id='01' group by c_id),2))avgscore from score s1 where c_id='01')
union
    (select distinct c_id ,(round((select avg(s_score) from score
        where c_id='02' group by c_id),2))avgscore from score s1 where c_id='02')
union
    (select distinct c_id ,(round((select avg(s_score) from score
        where c_id='03' group by c_id),2))avgscore from score s1 where c_id='03')
)tmp ,course where tmp.c_id=course.c_id order by tmp.avgscore desc;

–方法2

select course.c_id,course.t_id,t_name,round(avg(s_score),2)as avgscore from course
    join teacher on teacher.t_id=course.t_id
    join score on course.c_id=score.c_id
    group by score.c_id order by avgscore desc;

–方法3

select course.c_id,course.t_id,t_name,round(avg(s_score),2)as avgscore from course,teacher,score
   where teacher.t_id=course.t_id and course.c_id=score.c_id
    group by score.c_id order by avgscore desc;

– 22、查詢所有課程的成績第2名到第3名的學生資訊及該課程成績
–方法1

(select student.*,tmp1.c_id,tmp1.s_score from student,
    (select s_id,c_id,s_score from score where c_id='01' order by s_score desc limit 1,2)tmp1
        where student.s_id=tmp1.s_id)
union(select student.*,tmp2.c_id,tmp2.s_score from student,
    (select s_id,c_id,s_score from score where c_id='02' order by s_score desc limit 1,2)tmp2
        where student.s_id=tmp2.s_id)
union(select student.*,tmp3.c_id,tmp3.s_score from student,
    (select s_id,c_id,s_score from score where c_id='03' order by s_score desc limit 1,2)tmp3
        where student.s_id=tmp3.s_id);

–方法2

(select student.*,tmp.c_id,tmp.s_score,tmp.排名 from(
    select a.s_id,a.c_id,a.s_score,@i:[email protected]+1 as 排名 from score a,(select @i:=0)b
      where a.c_id='01' order by a.s_score desc
)tmp join student on tmp.s_id=student.s_id where 排名 between 2 and 3)
union (
select student.*,tmp.c_id,tmp.s_score,tmp.排名 from(
    select a.s_id,a.c_id,a.s_score,@j:[email protected]+1 as 排名 from score a,(select @j:=0)b
      where a.c_id='02' order by a.s_score desc
)tmp join student on tmp.s_id=student.s_id where 排名 between 2 and 3
)union (
select student.*,tmp.c_id,tmp.s_score,tmp.排名 from(
    select a.s_id,a.c_id,a.s_score,@k:[email protected]+1 as 排名 from score a,(select @k:=0)b
      where a.c_id='03' order by a.s_score desc
)tmp join student on tmp.s_id=student.s_id where 排名 between 2 and 3);

– 23、統計各科成績各分數段人數:課程編號,課程名稱,[100-85],[85-70],[70-60],[0-60]及所佔百分比

select c.c_id,c.c_name,tmp1.`[0-60]`, tmp1.`百分比`,tmp2.`[60-70]`, tmp2.`百分比`,tmp3.`[70-85]`, tmp3.`百分比`,tmp4.`[85-100]`, tmp4.`百分比` from course c
join
(select c_id,sum(case when s_score<60 then 1 else 0 end )as '[0-60]',
    round(100*sum(case when s_score<60 then 1 else 0 end )/sum(case when s_score then 1 else 0 end ),2)as 百分比
from score group by c_id)tmp1 on tmp1.c_id =c.c_id
join
(select c_id,sum(case when s_score<70 and s_score>=60 then 1 else 0 end )as '[60-70]',
    round(100*sum(case when s_score<70 and s_score>=60 then 1 else 0 end )/sum(case when s_score then 1 else 0 end ),2)as 百分比
from score group by c_id)tmp2 on tmp2.c_id =c.c_id
join
(select c_id,sum(case when s_score<85 and s_score>=70 then 1 else 0 end )as '[70-85]',
    round(100*sum(case when s_score<85 and s_score>=70 then 1 else 0 end )/sum(case when s_score then 1 else 0 end ),2)as 百分比
from score group by c_id)tmp3 on tmp3.c_id =c.c_id
join
(select c_id,sum(case when s_score>=85 then 1 else 0 end )as '[85-100]',
    round(100*sum(case when s_score>=85 then 1 else 0 end )/sum(case when s_score then 1 else 0 end ),2)as 百分比
from score group by c_id)tmp4 on tmp4.c_id =c.c_id;

– 24、查詢學生平均成績及其名次

select a.s_id,a.s_name,a.平均分,@i:[email protected]+1 as 排名 from
    (select student.s_id,student.s_name,avg(score.s_score) as "平均分"  from student,score
        where student.s_id=score.s_id
        group by score.s_id order by `平均分` desc)a,
    (select @i:=0)b;

– 25、查詢各科成績前三名的記錄
– 1.選出b表比a表成績大的所有組
– 2.選出比當前id成績大的 小於三個的
–沒有查學生姓名

(select score.c_id,course.c_name,s_score from score,course
    where score.c_id='01'and course.c_id=score.c_id order by s_score desc limit 3)
union
(select score.c_id,course.c_name,s_score from score,course
    where score.c_id='02'and course.c_id=score.c_id order by s_score desc limit 3)
union
(select score.c_id,course.c_name,s_score from score,course
    where score.c_id='03'and course.c_id=score.c_id order by s_score desc limit 3);

–查了學生姓名

(select score.c_id,course.c_name,student.s_name,s_score from score
    join student on student.s_id=score.s_id
    join course on  score.c_id='01' and course.c_id=score.c_id  order by s_score desc limit 3)
union (
select score.c_id,course.c_name,student.s_name,s_score from score
    join student on student.s_id=score.s_id
    join course on  score.c_id='02' and course.c_id=score.c_id  order by s_score desc limit 3

)union (
select score.c_id,course.c_name,student.s_name,s_score from score
    join student on student.s_id=score.s_id
    join course on  score.c_id='03' and course.c_id=score.c_id  order by s_score desc limit 3);

– 26、查詢每門課程被選修的學生數

select c.c_id,c.c_name,a.`被選修人數` from course c
    join (select c_id,count(1) as `被選修人數` from score
        where score.s_score<60 group by score.c_id)a
    on a.c_id=c.c_id;

– 27、查詢出只有兩門課程的全部學生的學號和姓名

select st.s_id,st.s_name from student st
  join (select s_id from score group by s_id having count(c_id) =2)a
    on st.s_id=a.s_id;

– 28、查詢男生、女生人數

select a.男生人數,b.女生人數 from
    (select count(1) as 男生人數 from student where s_sex='男')a,
    (select count(1) as 女生人數 from student where s_sex='女')b;

– 29、查詢名字中含有"風"字的學生資訊

select * from student where s_name like '%風%';

– 30、查詢同名同性學生名單,並統計同名人數

select s1.s_id,s1.s_name,s1.s_sex,count(*) as 同名人數  from student s1,student s2
    where s1.s_name=s2.s_name and s1.s_id<>s2.s_id and s1.s_sex=s2.s_sex
    group by s1.s_name,s1.s_sex;

– 31、查詢1990年出生的學生名單

select * from student where s_birth like '1990%';

– 32、查詢每門課程的平均成績,結果按平均成績降序排列,平均成績相同時,按課程編號升序排列

select score.c_id,c_name,round(avg(s_score),2) as 平均成績 from score
  join course on score.c_id=course.c_id
    group by c_id order by `平均成績` desc,score.c_id asc;

– 33、查詢平均成績大於等於85的所有學生的學號、姓名和平均成績

select score.s_id,s_name,round(avg(s_score),2)as 平均成績 from score
    join student on student.s_id=score.s_id
    group by score.s_id having `平均成績` >= 85;

– 34、查詢課程名稱為"數學",且分數低於60的學生姓名和分數

select s_name,s_score as 數學成績 from student
    join (select s_id,s_score from score,course where score.c_id=course.c_id and c_name='數學')a
    on a.s_score < 60 and student.s_id=a.s_id;

– 35、查詢所有學生的課程及分數情況

select a.s_name,
    SUM(case c.c_name when '語文' then b.s_score else 0 end ) as 語文,
    SUM(case c.c_name when '數學' then b.s_score else 0 end ) as 數學,
    SUM(case c.c_name when '英語' then b.s_score else 0 end ) as 英語,
    SUM(b.s_score) as 總分
  from student a
    join score b on a.s_id=b.s_id
    join course c on b.c_id=c.c_id
    group by s_name,a.s_id;

– 36、查詢任何一門課程成績在70分以上的學生姓名、課程名稱和分數

select s_name,c_name,s_score from score
    join student on student.s_id=score.s_id
    join course on score.c_id=course.c_id
  where s_score < 70;

– 37、查詢不及格的課程

select s_name,c_name as 不及格課程,tmp.s_score from student
    join (select s_id,s_score,c_name from score,course where score.c_id=course.c_id and s_score < 60)tmp
    on student.s_id=tmp.s_id;

–38、查詢課程編號為01且課程成績在80分以上的學生的學號和姓名

select student.s_id,s_name,s_score as score_01 from student
    join score on student.s_id=score.s_id
    where c_id='01' and s_score >= 80;

– 39、求每門課程的學生人數

select course.c_id,course.c_name,count(1)as 選課人數 from course
    join score on course.c_id=score.c_id
    group by score.c_id;

– 40、查詢選修"張三"老師所授課程的學生中,成績最高的學生資訊及其成績
– 查詢老師id

select t_id,t_name from teacher where t_name='張三';

– 查詢最高分(可能有相同分數)

  select s_id,c_name,max(s_score) from score
      join (select course.c_id,c_name from course,
                (select t_id,t_name from teacher where t_name='張三')tmp
            where course.t_id=tmp.t_id)tmp2
      on score.c_id=tmp2.c_id;

– 查詢資訊

   select student.*,tmp3.c_name as 課程名稱,tmp3.最高分 from student
        join (select s_id,c_name,max(s_score)as 最高分 from score
                join (select course.c_id,c_name from course,
                      (select t_id,t_name from teacher where t_name='張三')tmp
                   where course.t_id=tmp.t_id)tmp2
                on score.c_id=tmp2.c_id)tmp3
        on student.s_id=tmp3.s_id;

– 41、查詢不同課程成績相同的學生的學生編號、課程編號、學生成績

select distinct a.s_id,a.c_id,a.s_score from score a,score b
    where a.c_id <> b.c_id and a.s_score=b.s_score;

– 42、查詢每門課程成績最好的前兩名
–方法1(該方法有bug,不能查出臨界的重複值,例如查各科的第一名或前三名)

select a.s_id,a.c_id,a.s_score from score a
    where (select count(1) from score b where a.c_id=b.c_id and b.s_score >= a.s_score) < 2
    order by a.c_id asc ,a.s_score desc;

–方法2(查前三名)

(select * from score where c_id ='01' order by s_score desc limit 3)
union (
select * from score where c_id ='02' order by s_score desc limit 3)
union (
select * from score where c_id ='03' order by s_score desc limit 3);

– 43、統計每門課程的學生選修人數(超過5人的課程才統計)。要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列

select distinct course.c_id,tmp.選修人數 from course
    join (select c_id,count(1) as 選修人數 from score group by c_id)tmp
    where tmp.選修人數>=5 order by tmp.選修人數 desc ,course.c_id asc;

– 44、檢索至少選修兩門課程的學生學號

select s_id,count(c_id) as totalCourse from score group by s_id having count(c_id) >= 2;

– 45、查詢選修了全部課程的學生資訊

select student.* from 
		student,(select s_id,count(c_id) as totalCourse from score group by s_id)tmp
    where student.s_id=tmp.s_id and totalCourse=3;

–46、查詢各學生的年齡
– 按照出生日期來算,當前月日 < 出生年月的月日則,年齡減一

select s_name,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 1 else 0 end ) as age
    from student;

– 47、查詢本週過生日的學生
–方法1

select * from student where WEEK(DATE_FORMAT(NOW(),'%Y%m%d'))+1 =WEEK(s_birth);

–方法2

select s_name,s_sex,s_birth from student
    where substring(s_birth,6,2)='10'
    and substring(s_birth,9,2)=14;

– 48、查詢下週過生日的學生
–方法1

select * from student where WEEK(DATE_FORMAT(NOW(),'%Y%m%d'))+1 =WEEK(s_birth);

–方法2

select s_name,s_sex,s_birth from student
    where substring(s_birth,6,2)='10'
    and substring(s_birth,9,2)>=15
    and substring(s_birth,9,2)<=21;

– 49、查詢本月過生日的學生
–方法1

select * from student where MONTH(DATE_FORMAT(NOW(),'%Y%m%d'))+1 =MONTH(s_birth);

–方法2

select s_name,s_sex,s_birth from student where substring(s_birth,6,2)='10';

– 50、查詢12月份過生日的學生

select s_name,s_sex,s_birth from student where substring(s_birth,6,2)='12';

練習中遇到的部分方法彙總:
查詢的執行順序:

1. from : 表名         
2. where:條件過濾
  (定義別名)
3. group by : 分組
  (聚合函式執行)
4. having : 分組之後進行過濾。
5 select :執行完畢之後,查詢內容。
6.order by : 排序輸出顯示.
7.limit

nvl(COMMISSION_PCT,0) 第一個引數為非null則返回第一個引數;第一個引數為null則返回第二個引數

COALESCE(EXPR1,EXPR2,EXPR3…EXPRn) 從左往右數,遇到第一個非null值,則返回該非null值。
多層判斷:
第一點區別:從上面可以知道,nvl只適合於兩個引數的,COALESCE適合於多個引數。
第二點區別:COALESCE裡的所有引數型別必須保持一致,nvl可以不一致。

decode(name,‘apple’,0) 如果 name = ‘apple’ 那麼返回 0;否則的話 , 就是返回 null 了。

round(DOUBLE a) 返回對a四捨五入的BIGINT值

round(DOUBLE a, INT d) 返回DOUBLE型d的保留n位小數的DOUBLW型的近似值

rand(), rand(INT seed) 每行返回一個DOUBLE型隨機數seed是隨機因子(mysql沒有rank函式)

concat()函式
1、功能:將多個字串連線成一個字串。
2、語法:concat(str1, str2,…)
返回結果為連線引數產生的字串,如果有任何一個引數為null,則返回值為null。

concat_ws()函式
1、功能:和concat()一樣,將多個字串連線成一個字串,但是可以一次性指定分隔符~(concat_ws就是concat with separator)
2、語法:concat_ws(separator, str1, str2, …)
說明:第一個引數指定分隔符。需要注意的是分隔符不能為null,如果為null,則返回結果為null。

group_concat()
1、功能:將group by產生的同一個分組中的值連線起來,返回一個字串結果。
2、語法:group_concat( [distinct] 要連線的欄位 [order by 排序欄位 asc/desc ] [separator ‘分隔符’] )
說明:通過使用distinct可以排除重複值;如果希望對結果中的值進行排序,可以使用order by子句;separator是一個字串值,預設為一個逗號。

count(*) 和 count(1)和count(列名)區別:
執行效果上:
count()包括了所有的列,相當於行數,在統計結果的時候,不會忽略列值為NULL
count(1)包括了忽略所有列,用1代表程式碼行,在統計結果的時候,不會忽略列值為NULL
count(列名)只包括列名那一列,在統計結果的時候,會忽略列值為空(這裡的空不是隻空字串或者0,而是表示null)的計數,即某個欄位值為NULL時,不統計。
執行效率上:
列名為主鍵,count(列名)會比count(1)快
列名不為主鍵,count(1)會比count(列名)快
如果表多個列並且沒有主鍵,則 count(1) 的執行效率優於 count(

如果有主鍵,則 select count(主鍵)的執行效率是最優的
如果表只有一個欄位,則 select count(*)最優。

Case具有兩種格式:簡單Case函式和Case搜尋函式
–簡單Case函式
CASE sex ------如果
WHEN ‘1’ THEN ‘男’ ------sex=‘1’,則返回值’男’
WHEN ‘2’ THEN ‘女’ ------sex=‘2’,則返回值’女’
ELSE ‘其他’ ------其他的返回’其他’
END ------結束

–Case搜尋函式
CASE WHEN sex = ‘1’ THEN ‘男’
WHEN sex = ‘2’ THEN ‘女’
ELSE ‘其他’ END

MySQL儲存過程中,定義變數有兩種方式:
第一種用法:set @num=1; 或 set @num:=1; //這裡要使用變數來儲存資料,直接使用@num變數
第二種用法:select @num:=1; 或 select @num:=欄位名 from 表名 where ……
注意上面兩種賦值符號,使用set時可以用“=”或“:=”,但是使用select時必須用“:=賦值”

1.使用set或select直接賦值,變數名以 @ 開頭.
可以在一個會話的任何地方宣告,作用域是整個會話,稱為使用者變數。
2.以 DECLARE 關鍵字宣告的變數,只能在儲存過程中使用,稱為儲存過程變數.
例如: DECLARE var1 INT DEFAULT 0;
主要用在儲存過程中,或者是給儲存傳引數中。
兩者的區別是:
在呼叫儲存過程時,以DECLARE宣告的變數都會被初始化為 NULL。
而會話變數(即@開頭的變數)則不會被再初始化,在一個會話內,只須初始化一次,
之後在會話內都是對上一次計算的結果,就相當於在是這個會話內的全域性變數。

MySQL的4種變數:
1、區域性變數(只在當前begin/end程式碼塊中有效)
區域性變數定義語法形式: DECLARE var_name [, var_name]… data_type [ DEFAULT value ];
2、使用者變數(在客戶端連結到資料庫例項整個過程中使用者變數都是有效的)
定義:
select @變數名 或者 select @變數名:= 欄位名 from 表名 where 過濾語句;
set @變數名;
賦值:
@num為變數名,value為值
set @num=value; 或 select @num:=value;
3、會話變數(伺服器為每個連線的客戶端維護一系列會話變數)
設定會話變數有如下三種方式更改會話變數的值:
set session var_name = value;
set @@session.var_name = value;
set var_name = value; #預設session關鍵字預設認為是session
檢視所有的會話變數: SHOW SESSION VARIABLES;
4、全域性變數(全域性變數影響伺服器整體操作。當伺服器啟動時,它將所有全域性變數初始化為預設值)(想要更改全域性變數的值,需要擁有SUPER許可權)
要設定一個全域性變數,有如下兩種方式:
set global var_name = value; //注意:此處的global不能省略。根據手冊,set命令設定變數時若不指定GLOBAL、SESSION或者LOCAL,預設使用SESSION
set @@global.var_name = value; //同上
檢視所有的全域性變數: show global variables;
要想檢視一個全域性變數,有如下兩種方式:
select @@global.var_name;
show global variables like “%var%”;
會話變數和全域性變數叫系統變數。
系統變數在變數名前面有兩個@;
  如果想要更改會話變數的值,利用語句:
set session varname = value; 或者 set @@session.varname = value;

獲取字串型別的別名:
用 `` (飄號,Tab鍵上面的那個符號)
例如:
select c_id,avg(s_score) as 平均成績 from score group by c_id order by 平均成績 desc

sql 擷取字串

1.substring 返回字元、binary、text 或 image 表示式的一部分。
基本語法:SUBSTRING ( expression , start , length )
expression:字串、二進位制字串、text、image、列或包含列的表示式
start:整數,指定子串的開始位置 注:SQL中"1"表示字串中的第一個字元,而.NET中"0"表示第一個字元
length:整數,指定子串的長度(要返回的字元數或位元組數)

2.patindex 返回指定表示式中某模式第一次出現的起始位置;如果在全部有效的文字和字元資料型別中沒有找到該模式,則返回零。
基本語法:PATINDEX ( ‘%pattern%’ , expression )
pattern:字串。可以使用萬用字元,但 pattern 之前和之後必須有 % 字元(搜尋第一個和最後一個字元時除外)。pattern 是短字元資料型別類別的表示式
expression:表示式,通常為要在其中搜索指定模式的列,expression 為字串資料型別類別

MySQL:
  1、LOCATE(substr , str ):返回子串 substr 在字串 str 中第一次出現的位置,如果字元substr在字串str中不存在,則返回0;
  2、POSITION(substr IN str ):返回子串 substr 在字串 str 中第一次出現的位置,如果字元substr在字串str中不存在,與LOCATE函式作用相同;
  3、LEFT(str, length):從左邊開始擷取str,length是擷取的長度;
  4、RIGHT(str, length):從右邊開始擷取str,length是擷取的長度;
  5、SUBSTRING_INDEX(str ,substr ,n):返回字元substr在str中第n次出現位置之前的字串;
  6、SUBSTRING(str ,n ,m):返回字串str從第n個字元擷取到第m個字元;
  7、REPLACE(str, n, m):將字串str中的n字元替換成m字元;
  8、LENGTH(str):計算字串str的長度;
  MySQL函式大全:http://www.jb51.net/article/42906.htm
sqlserver:
  1、CHARINDEX(substr ,str):返回子串 substr 在字串 str 中第一次出現的位置,如果字元substr在字串str中不存在,則返回0;
  2、LEFT(str, length):從左邊開始擷取str,length是擷取的長度;
  3、RIGHT(str, length):從右邊開始擷取str,length是擷取的長度;
  4、SUBSTRING(str ,n ,m):返回字串str從第n個字元擷取到第m個字元;
  5、REPLACE(str, n, m):將字串str中的n字元替換成m字元;
  6、LEN(str):計算字串str的長度;
  sqlserver函式大全:https://wenku.baidu.com/view/e2e19dec172ded630b1cb628.html###
oracle:
  1、SUBSTR(string,start_position,[length]) 求子字串,返回字串;
    a、substr(“ABCDEFG”, 0);//返回:ABCDEFG,擷取所有字元;
    b、substr(“ABCDEFG”, 2);//返回:CDEFG,擷取從C開始之後所有字元;
    c、substr(“ABCDEFG”, 0, 3);//返回:ABC,擷取從A開始3個字元;
    d、substr(“ABCDEFG”, 0, 100);//返回:ABCDEFG,100雖然超出預處理的字串最長度,但不會影響返回結果,系統按預處理字串最大數量返回;
    e、substr(“ABCDEFG”, -3);//返回:EFG,注意引數-3,為負值時表示從尾部開始算起,字串排列位置不變;
  2、INSTR(string,subString,position,ocurrence)查詢字串位置;
     string:源字串
  subString:要查詢的子字串
  position:查詢的開始位置
  ocurrence:源字串中第幾次出現的子字串
  3、replace(strSource, str1, str2) 將strSource中的str1替換成str2;
  4、lengthb(string)計算string所佔的位元組長度:返回字串的長度,單位是位元組;
    length(string)計算string所佔的字元長度:返回字串的長度,單位是字元;
  oracle函式大全:https://wenku.baidu.com/view/2fb8f865580216fc700afd9c.html

sql中把字串轉化為數字的方法
1. convert(int,欄位名)
2. cast(欄位名 as int)
3. ‘123’+0;