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;