1. 程式人生 > >50道高階sql練習題;大大提高自己的sql能力(附具體的sql)

50道高階sql練習題;大大提高自己的sql能力(附具體的sql)

問題及描述:
--1.學生表
Student(SID,Sname,Sage,Ssex) --SID 學生編號,Sname 學生姓名,Sage 出生年月,Ssex 學生性別
--2.課程表
Course(CID,Cname,TID) --CID --課程編號,Cname 課程名稱,TID 教師編號
--3.教師表
Teacher(TID,Tname) --TID 教師編號,Tname 教師姓名
--4.成績表
SC(SID,CID,score) --SID 學生編號,CID 課程編號,score 分數
*/
--建立測試資料
create table Student(SID varchar(10),Sname nvarchar(10),Sage datetime,Ssex nvarchar(10));
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' , '');
create table Course(CID varchar(10),Cname nvarchar(10),TID varchar(10));
insert into Course values('01' , '語文' , '02');
insert into Course values('02' , '數學' , '01');
insert into Course values('03' , '英語
' , '03');
create table Teacher(TID varchar(10),Tname nvarchar(10));
insert into Teacher values('01' , '張三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');
create table SC(SID varchar(10),CID varchar(10),score decimal(18,1));
insert into SC values('01' , '01' , 80);
insert into SC values('01' , '02' , 90);
insert into SC values('01' , '03' , 99);
insert into SC values('02' , '01' , 70);
insert into SC values('02' , '02' , 60);
insert into SC values('02' , '03' , 80);
insert into SC values('03' , '01' , 80);
insert into SC values('03' , '02' , 80);
insert into SC values('03' , '03' , 80);
insert into SC values('04' , '01' , 50);
insert into SC values('04' , '02' , 30);
insert into SC values('04' , '03' , 20);
insert into SC values('05' , '01' , 76);
insert into SC values('05' , '02' , 87);
insert into SC values('06' , '01' , 31);
insert into SC values('06' , '03' , 34);
insert into SC values('07' , '02' , 89);
insert into SC values('07' , '03' , 98);

--1、查詢"01"課程比"02"課程成績高的學生的資訊及課程分數
--1.1、查詢同時存在"01"課程和"02"課程的情況
select a.* , b.score 課程01的分數,c.score 課程02的分數 from Student a , SC b , SC c
where a.SID = b.SID and a.SID = c.SID and b.CID = '01' and c.CID = '02' and b.score > c.score
--1.2、查詢同時存在"01"課程和"02"課程的情況和存在"01"課程但可能不存在"02"課程的情況(不存在時顯示為null)(以下存在相同內容時不再解釋)
select a.* , b.score 課程01的分數,c.score 課程02的分數 from Student a
left join SC b on a.SID = b.SID and b.CID = '01'
left join SC c on a.SID = c.SID and c.CID = '02'
where b.score > isnull(c.score,0)

--2、查詢"01"課程比"02"課程成績低的學生的資訊及課程分數
--2.1、查詢同時存在"01"課程和"02"課程的情況
select a.* , b.score  課程01的分數 ,c.score  課程02的分數  from Student a , SC b , SC c
where a.SID = b.SID and a.SID = c.SID and b.CID = '01' and c.CID = '02' and b.score < c.score
--2.2、查詢同時存在"01"課程和"02"課程的情況和不存在"01"課程但存在"02"課程的情況
select a.* , b.score  課程01的分數 ,c.score  課程02的分數  from Student a
left join SC b on a.SID = b.SID and b.CID = '01'
left join SC c on a.SID = c.SID and c.CID = '02'
where isnull(b.score,0) < c.score

--3、查詢平均成績大於等於60分的同學的學生編號和學生姓名和平均成績
select a.SID , a.Sname , cast(avg(b.score) as decimal(18,2)) avg_score
from Student a , sc b
where a.SID = b.SID
group by a.SID , a.Sname
having cast(avg(b.score) as decimal(18,2)) >= 60
order by a.SID

--4、查詢平均成績小於60分的同學的學生編號和學生姓名和平均成績
--4.1、查詢在sc表存在成績的學生資訊的SQL語句。
select a.SID , a.Sname , cast(avg(b.score) as decimal(18,2)) avg_score
from Student a , sc b
where a.SID = b.SID
group by a.SID , a.Sname
having cast(avg(b.score) as decimal(18,2)) < 60
order by a.SID
--4.2、查詢在sc表中不存在成績的學生資訊的SQL語句。
select a.SID , a.Sname , isnull(cast(avg(b.score) as decimal(18,2)),0) avg_score
from Student a left join sc b
on a.SID = b.SID
group by a.SID , a.Sname
having isnull(cast(avg(b.score) as decimal(18,2)),0) < 60
order by a.SID

--5、查詢所有同學的學生編號、學生姓名、選課總數、所有課程的總成績
--5.1、查詢所有有成績的SQL
select a.SID  學生編號 , a.Sname  學生姓名 , count(b.CID) 選課總數, sum(score)  所有課程的總成績 
from Student a , SC b
where a.SID = b.SID
group by a.SID,a.Sname
order by a.SID
--5.2、查詢所有(包括有成績和無成績)SQL
select a.SID  學生編號 , a.Sname  學生姓名 , count(b.CID) 選課總數, sum(score)  所有課程的總成績 
from Student a left join SC b
on a.SID = b.SID
group by a.SID,a.Sname
order by a.SID

--6、查詢""姓老師的數量
--方法1
select count(Tname)  李姓老師的數量  from Teacher where Tname like '%'
--方法2
select count(Tname)  李姓老師的數量  from Teacher where left(Tname,1) = ''

--7、查詢學過"張三"老師授課的同學的資訊
select distinct Student.* from Student , SC , Course , Teacher
where Student.SID = SC.SID and SC.CID = Course.CID and Course.TID = Teacher.TID and Teacher.Tname = '張三'
order by Student.SID

--8、查詢沒學過"張三"老師授課的同學的資訊
select m.* from Student m where SID not in (select distinct SC.SID from SC , Course , Teacher where SC.CID = Course.CID and Course.TID = Teacher.TID and Teacher.Tname = '張三') order by m.SID

--9、查詢學過編號為"01"並且也學過編號為"02"的課程的同學的資訊
--方法1
select Student.* from Student , SC where Student.SID = SC.SID and SC.CID = '01' and exists (Select 1 from SC SC_2 where SC_2.SID = SC.SID and SC_2.CID = '02') order by Student.SID
--方法2
select Student.* from Student , SC where Student.SID = SC.SID and SC.CID = '02' and exists (Select 1 from SC SC_2 where SC_2.SID = SC.SID and SC_2.CID = '01') order by Student.SID
--方法3
select m.* from Student m where SID in
(
  select SID from
  (
    select distinct SID from SC where CID = '01'
    union all
    select distinct SID from SC where CID = '02'
  ) t group by SID having count(1) = 2
)
order by m.SID

--10、查詢學過編號為"01"但是沒有學過編號為"02"的課程的同學的資訊
--方法1
select Student.* from Student , SC where Student.SID = SC.SID and SC.CID = '01' and not exists (Select 1 from SC SC_2 where SC_2.SID = SC.SID and SC_2.CID = '02') order by Student.SID
--方法2
select Student.* from Student , SC where Student.SID = SC.SID and SC.CID = '01' and Student.SID not in (Select SC_2.SID from SC SC_2 where SC_2.SID = SC.SID and SC_2.CID = '02') order by Student.SID

--11、查詢沒有學全所有課程的同學的資訊
--11.1
select Student.*
from Student , SC
where Student.SID = SC.SID
group by Student.SID , Student.Sname , Student.Sage , Student.Ssex having count(CID) < (select count(CID) from Course)
--11.2
select Student.*
from Student left join SC
on Student.SID = SC.SID
group by Student.SID , Student.Sname , Student.Sage , Student.Ssex having count(CID) < (select count(CID) from Course)

--12、查詢至少有一門課與學號為"01"的同學所學相同的同學的資訊
select distinct Student.* from Student , SC where Student.SID = SC.SID and SC.CID in (select CID from SC where SID = '01') and Student.SID <> '01'

--13、查詢和"01"號的同學學習的課程完全相同的其他同學的資訊
select Student.* from Student where SID in
(select distinct SC.SID from SC where SID <> '01' and SC.CID in (select distinct CID from SC where SID = '01')
group by SC.SID having count(1) = (select count(1) from SC where SID='01'))

--14、查詢沒學過"張三"老師講授的任一門課程的學生姓名
select student.* from student where student.SID not in
(select distinct sc.SID from sc , course , teacher where sc.CID = course.CID and course.TID = teacher.TID and teacher.tname = '張三')
order by student.SID

--15、查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績
select student.SID , student.sname , cast(avg(score) as decimal(18,2)) avg_score from student , sc
where student.SID = SC.SID and student.SID in (select SID from SC where score < 60 group by SID having count(1) >= 2)
group by student.SID , student.sname

--16、檢索"01"課程分數小於60,按分數降序排列的學生資訊
select student.* , sc.CID , sc.score from student , sc
where student.SID = SC.SID and sc.score < 60 and sc.CID = '01'
order by sc.score desc

--17、按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績
--17.1 SQL 2000 靜態
select a.SID 學生編號 , a.Sname 學生姓名 ,
       max(case c.Cname when '語文' then b.score else null end)  語文 ,
       max(case c.Cname when '數學' then b.score else null end)  數學 ,
       max(case c.Cname when '英語' then b.score else null end)  英語 ,
       cast(avg(b.score) as decimal(18,2)) 平均分
from Student a
left join SC b on a.SID = b.SID
left join Course c on b.CID = c.CID
group by a.SID , a.Sname
order by 平均分 desc
--17.2 SQL 2000 動態
declare @sql nvarchar(4000)
set @sql = 'select a.SID ' + '學生編號' + ' , a.Sname ' + '學生姓名'
select @sql = @sql + ',max(case c.Cname when '''+Cname+''' then b.score else null end)  '+Cname+' '
from (select distinct Cname from Course) as t
set @sql = @sql + ' , cast(avg(b.score) as decimal(18,2)) ' + '平均分' + ' from Student a left join SC b on a.SID = b.SID left join Course c on b.CID = c.CID
group by a.SID , a.Sname order by ' + '平均分' + ' desc'
exec(@sql)

--18、查詢各科成績最高分、最低分和平均分:以如下形式顯示:課程ID,課程name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率--及格為>=60,中等為:70-80,優良為:80-90,優秀為:>=90--方法1select m.CID  課程編號 , m.Cname  課程名稱 , max(n.score)  最高分 ,min(n.score)  最低分 ,cast(avg(n.score) asdecimal(18,2))  平均分 ,cast((selectcount(1) from SC where CID = m.CID and score >=60)*100.0/ (selectcount(1) from SC where CID = m.CID) asdecimal(18,2))  及格率 ,cast((selectcount(1) from SC where CID = m.CID and score >=70and score <80 )*100.0/ (selectcount(1) from SC where CID = m.CID) asdecimal(18,2))  中等率 ,cast((selectcount(1) from SC where CID = m.CID and score >=80and score <90 )*100.0/ (selectcount(1) from SC where CID = m.CID) asdecimal(18,2))  優良率 ,cast((selectcount(1) from SC where CID = m.CID and score >=90)*100.0/ (selectcount(1) from SC where CID = m.CID) asdecimal(18,2))  優秀率 from Course m , SC nwhere m.CID = n.CIDgroupby m.CID , m.Cnameorderby m.CID--方法2select m.CID  課程編號 , m.Cname  課程名稱 ,   (selectmax(score) from SC where CID = m.CID)  最高分 ,  (selectmin(score) from SC where CID = m.CID)  最低分 ,  (selectcast(avg(score) asdecimal(18,2)) from SC where CID = m.CID)  平均分 ,cast((selectcount(1) from SC where CID = m.CID and score >=60)*100.0/ (selectcount(1) from SC where CID = m.CID) asdecimal(18,2))  及格率,cast((selectcount(1) from SC where CID = m.CID and score >=70and score <80 )*100.0/ (selectcount(1) from SC where CID = m.CID) asdecimal(18,2))  中等率 ,cast((selectcount(1) from SC where CID = m.CID and score >=80and score <90 )*100.0/ (selectcount(1) from SC where CID = m.CID) asdecimal(18,2))  優良率 ,cast((selectcount(1) from SC where CID = m.CID and score >=90)*100.0/ (selectcount(1) from SC where CID = m.CID) asdecimal(18,2))  優秀率from Course m orderby m.CID--19、按各科成績進行排序,並顯示排名--19.1 sql 2000用子查詢完成--Score重複時保留名次空缺select t.* , px = (selectcount(1) from SC where CID = t.CID and score > t.score) +1from sc t orderby t.cid , px --Score重複時合併名次select t.* , px = (selectcount(distinct score) from SC where CID = t.CID and score >= t.score) from sc t orderby t.cid , px --19.2 sql 2005用rank,DENSE_RANK完成--Score重複時保留名次空缺(rank完成)select t.* , px = rank() over(partition by cid orderby score desc) from sc t orderby t.CID , px --Score重複時合併名次(DENSE_RANK完成)select t.* , px = DENSE_RANK() over(partition by cid orderby score desc) from sc t orderby t.CID , px --20、查詢學生的總成績並進行排名--20.1 查詢學生的總成績select m.SID  學生編號  ,        m.Sname  學生姓名  ,isnull(sum(score),0)  總成績 from Student m leftjoin SC n on m.SID = n.SID groupby m.SID , m.Snameorderby 總成績 desc--20.2 查詢學生的總成績並進行排名,sql 2000用子查詢完成,分總分重複時保留名次空缺和不保留名次空缺兩種。select t1.* , px = (selectcount(1) from(select m.SID  學生編號  ,          m.Sname  學生姓名  ,isnull(sum(score),0)  總成績 from Student m leftjoin SC n on m.SID = n.SID groupby m.SID , m.Sname) t2 where 總成績 > t1.總成績) +1from(select m.SID  學生編號  ,          m.Sname  學生姓名  ,isnull(sum(score),0)  總成績 from Student m leftjoin SC n on m.SID = n.SID groupby m.SID , m.Sname) t1orderby pxselect t1.* , px = (selectcount(distinct 總成績) from(select m.SID  學生編號  ,          m.Sname  學生姓名  ,isnull(sum(score),0)  總成績 from Student m leftjoin SC n on m.SID = n.SID groupby m.SID , m.Sname) t2 where 總成績 >= t1.總成績) from(select m.SID  學生編號  ,          m.Sname  學生姓名  ,isnull(sum(score),0)  總成績 from Student m leftjoin SC n on m.SID = n.SID groupby m.SID , m.Sname) t1orderby px--20.3 查詢學生的總成績並進行排名,sql 2005用rank,DENSE_RANK完成,分總分重複時保留名次空缺和不保留名次空缺兩種。select t.* , px = rank() over(orderby 總成績 desc) from(select m.SID  學生編號  ,          m.Sname  學生姓名  ,isnull(sum(score),0)  總成績 from Student m leftjoin SC n on m.SID = n.SID groupby m.SID , m.Sname) torderby pxselect t.* , px = DENSE_RANK() over(orderby 總成績 desc) from(select m.SID  學生編號  ,          m.Sname  學生姓名  ,isnull(sum(score),0)  總成績 from Student m leftjoin SC n on m.SID = n.SID groupby m.SID , m.Sname) torderby px--21、查詢不同老師所教不同課程平均分從高到低顯示 select m.TID , m.Tname , cast(avg(o.score) asdecimal(18,2)) avg_scorefrom Teacher m , Course n , SC owhere m.TID = n.TID and n.CID = o.CIDgroupby m.TID , m.Tnameorderby avg_score desc--22、查詢所有課程的成績第2名到第3名的學生資訊及該課程成績--22.1 sql 2000用子查詢完成--Score重複時保留名次空缺select*from (select t.* , px = (selectcount(1) from SC where CID = t.CID and score > t.score) +1from sc t) m where px between2and3orderby m.cid , m.px --Score重複時合併名次select*from (select t.* , px = (selectcount(distinct score) from SC where CID = t.CID and score >= t.score) from sc t) m where px between2and3orderby m.cid , m.px --22.2 sql 2005用rank,DENSE_RANK完成--Score重複時保留名次空缺(rank完成)select*from (select t.* , px = rank() over(partition by cid orderby score desc) from sc t) m where px between2and3orderby m.CID , m.px --Score重複時合併名次(DENSE_RANK完成)select*from (select t.* , px = DENSE_RANK() over(partition by cid orderby score desc) from sc t) m where px between2and3orderby m.CID , m.px --23、統計各科成績各分數段人數:課程編號,課程名稱, 100-85 , 85-70 , 70-60 , 0-60 及所佔百分比 --23.1 統計各科成績各分數段人數:課程編號,課程名稱, 100-85 , 85-70 , 70-60 , 0-60 --橫向顯示select Course.CID  課程編號  , Cname as 課程名稱  ,sum(casewhen score >=85then1else0end)  85-100 ,sum(casewhen score >=70and score <85then1else0end)  70-85 ,sum(casewhen score >=60and score <70then1else0end)  60-70 ,sum(casewhen score <60then1else0end)  0-60 from sc , Course where SC.CID = Course.CID groupby Course.CID , Course.Cnameorderby Course.CID--縱向顯示1(顯示存在的分數段)select m.CID  課程編號  , m.Cname  課程名稱  , 分數段 = (casewhen n.score >=85then'85-100'when n.score >=70and n.score <85then'70-85'when n.score >=60and n.score <70then'60-70'else'0-60'end) , count(1) 數量 from Course m , sc nwhere m.CID = n.CID groupby m.CID , m.Cname , (casewhen n.score >=85then'85-100'when n.score >=70and n.score <85then'70-85'when n.score >=60and n.score <70then'60-70'else'0-60'end)orderby m.CID , m.Cname , 分數段--縱向顯示2(顯示存在的分數段,不存在的分數段用0顯示)select m.CID  課程編號  , m.Cname  課程名稱  , 分數段 = (casewhen n.score >=85then'85-100'when n.score >=70and n.score <85then'70-85'when n.score >=60and n.score <70then'60-70'else'0-60'end) , count(1) 數量 from Course m , sc nwhere m.CID = n.CID groupbyall m.CID , m.Cname , (casewhen n.score >=85then'85-100'when n.score >=70and n.score <85then'70-85'when n.score >=60and n.score <70then'60-70'else'0-60'end)orderby m.CID , m.Cname , 分數段--23.2 統計各科成績各分數段人數:課程編號,課程名稱, 100-85 , 85-70 , 70-60 , <60 及所佔百分比 --橫向顯示select m.CID 課程編號, m.Cname 課程名稱,  (selectcount(1) from SC where CID = m.CID and score <60)  0-60 ,cast((selectcount(1) from SC where CID = m.CID and score <60)*100.0/ (selectcount(1) from SC where CID = m.CID) asdecimal(18,2))  百分比 ,  (selectcount(1) from SC where CID = m.CID and score >=60and score <70)  60-70 ,cast((selectcount(1) from SC where CID = m.CID and score >=60and score <