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:=@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 * 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:=@m+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:=@x+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:=@i+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:=@j+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:=@k+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:=@i+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;

猜你喜欢

转载自blog.csdn.net/Thomson617/article/details/83140926