现在的位置: 首页 > 数据库 > 正文

50个SQL语句

2019年06月01日 数据库 ⁄ 共 36088字 ⁄ 字号 评论关闭

一个项目用到的50个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分数

*/

--创建测试数据

createtable Student(Sidvarchar(10),Snamenvarchar(10),Sagedatetime,Ssex
nvarchar(10))

insertinto Studentvalues('01'
, N
'
赵雷' ,
'1990-01-01' , N'
')

insertinto Studentvalues('02'
, N
'
钱电' ,
'1990-12-21' , N'
')

insertinto Studentvalues('03'
, N
'
孙风' ,
'1990-05-20' , N'
')

insertinto Studentvalues('04'
, N
'
李云' ,
'1990-08-06' , N'
')

insertinto Studentvalues('05'
, N
'
周梅' ,
'1991-12-01' , N'
')

insertinto Studentvalues('06'
, N
'
吴兰' ,
'1992-03-01' , N'
')

insertinto Studentvalues('07'
, N
'
郑竹' ,
'1989-07-01' , N'
')

insertinto Studentvalues('08'
, N
'
王菊' ,
'1990-01-20' , N'
')

createtable Course(Cidvarchar(10),Cnamenvarchar(10),Tidvarchar(10))

insertinto Coursevalues('01'
, N
'
语文' ,
'02')

insertinto Coursevalues('02'
, N
'
数学' ,
'01')

insertinto Coursevalues('03'
, N
'
英语' ,
'03')

createtable Teacher(Tidvarchar(10),Tnamenvarchar(10))

insertinto Teachervalues('01'
, N
'
张三')

insertinto Teachervalues('02'
, N
'
李四')

insertinto Teachervalues('03'
, N
'
王五')

createtable SC(Sidvarchar(10),Cidvarchar(10),scoredecimal(18,1))

insertinto SCvalues('01'
,
'01' , 80)

insertinto SCvalues('01'
,
'02' , 90)

insertinto SCvalues('01'
,
'03' , 99)

insertinto SCvalues('02'
,
'01' , 70)

insertinto SCvalues('02'
,
'02' , 60)

insertinto SCvalues('02'
,
'03' , 80)

insertinto SCvalues('03'
,
'01' , 80)

insertinto SCvalues('03'
,
'02' , 80)

insertinto SCvalues('03'
,
'03' , 80)

insertinto SCvalues('04'
,
'01' , 50)

insertinto SCvalues('04'
,
'02' , 30)

insertinto SCvalues('04'
,
'03' , 20)

insertinto SCvalues('05'
,
'01' , 76)

insertinto SCvalues('05'
,
'02' , 87)

insertinto SCvalues('06'
,
'01' , 31)

insertinto SCvalues('06'
,
'03' , 34)

insertinto SCvalues('07'
,
'02' , 89)

insertinto SCvalues('07'
,
'03' , 98)

go

--1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数

思路:课程01(一个记录集合),课程02(一个记录集合),STUDENT表(一个记录集合),包含在这三个记录集合里,并且01分数>02分数的记录。

select*
fromstudent s inner
join(select*
from sc where cid='01') a

on s.sid=a.sidinnerjoin
(
select*
from
sc where cid='02') b

on s.sid=b.sidwherea.score>b.score

 

select a.*,b.*,c.*fromstudent a
innerjoinsc b

on a.sid=b.sidandb.cid='01'inner
join sc c

on a.sid=c.sidandc.cid='02'where
b.score>c.score

 

--1.1、查询同时存在"01"课程和"02"课程的情况

思路:课程01(一个记录集合),课程02(一个记录集合),STUDENT表(一个记录集合),包含在这三个记录集合里的记录。

select*
fromstudent s inner
join(select*
from sc where cid='01') a

on s.sid=a.sidinnerjoin
(select
*
from sc where cid='02') b

on s.sid=b.sidwherea.sid=b.sid

 

select s.*,a.*,b.*fromstudent s
innerjoinsc a

on s.sid=a.sidanda.cid='01'inner
joinsc b

on s.sid=b.sidandb.cid='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)(以下存在相同内容时不再解释)

思路:课程01(一个记录集合),课程02可能有,可能不存在(cid=’02’ or cid is null,STUDENT表(一个记录集合)

select*
fromstudent s inner
joinsc a

on s.sid=a.sidanda.cid='01'left
join sc b

on s.sid=b.sidand(b.cid='02'or
b.cid is
null)
where a.score>isnull(b.score,0)

 

select a.* , b.score[课程"01"的分数],c.score[课程"02"的分数]from
Student a
leftjoin SC b

on a.Sid= b.Sid
and b.Cid='01'leftjoin SC c

on a.Sid= c.Sid
and c.Cid='02'

where b.score>isnull(c.score,0)

 

--2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数

select*
fromstudent s inner
joinsc a

on s.sid=a.sidanda.cid='01'inner
join sc b

on s.sid=b.sidandb.cid='02'where
a.score<b.score

 

--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*
fromstudent s left
joinsc a

on s.sid=a.sidand(a.cid='01'or
a.cid is
null)
innerjoin sc b

on s.sid=b.sidandb.cid='02'

 

select*
fromstudent s inner
join

(select*
from sc where cid='02') aon s.sid=a.sidleft
join

(select*
from sc where
(
cid='01'or cid
is null)) b
on
s.sid=b.sid

 

select a.* , b.score[课程"01"的分数],c.score[课程"02"的分数]from
Student a

leftjoin SC bon a.Sid
= b.Sid and b.Cid='01'

leftjoin SC con a.Sid
= c.Sid and c.Cid='02'

whereisnull(b.score,0)<
c.score

 

--3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩

思路:平均成绩大于等于60分(一个记录集合),STUDENT表(一个记录集合)

select s.sid,s.sname,b.[平均成绩]fromstudent
s innerjoin

(select sid,convert(decimal(18,2),avg(score))as
'
平均成绩'from sc
group by sid
having
avg(score)>=60) b

on s.sid=b.sid

 

select*
fromstudent s inner
join

(select sid,avg(score)as
avgscore from scgroup
by sid having
avg
(score)>=60) a

on s.sid=a.sid

 

select a.Sid , a.Sname ,cast(avg(b.score)asdecimal(18,2))
avg_score

from Student a , sc b

where a.Sid= b.Sid

groupby a.Sid , a.Sname

havingcast(avg(b.score)asdecimal(18,2))>=60

orderby a.Sid

 

--4、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩

思路:平均成绩小于60分(一个记录集合),STUDENT(一个记录集合)

select s.sid,s.sname,b.[平均成绩]fromstudent
s innerjoin

(select sid,convert(decimal(18,2),avg(score))as
'
平均成绩'from sc
group by sid
having
avg(score)>60) b

on s.sid=b.sid

 

--4.1、查询在sc表存在成绩的学生信息的SQL语句。

思路:STUDENT表(一个记录集合)是否有记录包含在SC表(一个记录集合)

select*
fromstudent where sid
in(select sidfrom sc)

 

select*
fromstudent s where
exists(select 1from sc a
where s.sid=a.sid)

 

select a.Sid , a.Sname ,cast(avg(b.score)asdecimal(18,2))
avg_score

from Student a , sc b

where a.Sid= b.Sid

groupby a.Sid , a.Sname

havingcast(avg(b.score)asdecimal(18,2))<60

orderby a.Sid

 

--4.2、查询在sc表中不存在成绩的学生信息的SQL语句。

select
*
from student where sid not
in
(select distinct sid from sc)

 

select*
fromstudent s where
notexists(select 1
from sc a where s.sid=a.sid)

 

select a.Sid , a.Sname ,isnull(cast(avg(b.score)asdecimal(18,2)),0)
avg_score

from Student aleftjoin sc b

on a.Sid= b.Sid

groupby a.Sid , a.Sname

havingisnull(cast(avg(b.score)asdecimal(18,2)),0)<60

orderby a.Sid

 

--5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩

思路:SC表的选课总数、总成绩(一个记录集合),STUDENT表(一个记录集合)

select s.sid,s.sname,a.[选课总数],a.[总成绩]fromstudent
s innerjoin

(select sid,count(*)as
'
选课总数',sum(score)as
'
总成绩'from sc
group by sid) a

on s.sid=a.sid

 

select*
fromstudent s inner
join

(select sid,count(cid)as
'
课程总数',sum(score)as
'
课程总成绩'from sc
group by sid) a

on s.sid=a.sid

 

select s.sid,s.sname,count(a.cid)as
'
课程总数',sum(a.score)as
'
课程总成绩'from student s
innerjoin sc a

on s.sid=a.sidgroupby
s.sid,s.sname

 

--5.1、查询所有有成绩的SQL

select s.sid,s.sname,a.[选课总数],a.[总成绩]fromstudent
s innerjoin

(select sid,count(*)as
'
选课总数',sum(score)as
'
总成绩'from sc
group by sid) a

on s.sid=a.sid

 

select a.Sid[学生编号],
a.Sname
[
学生姓名],count(b.Cid)
选课总数,sum(score)
[
所有课程的总成绩]

from Student a , SC b

where a.Sid= b.Sid

groupby a.Sid,a.Sname

orderby a.Sid

 

--5.2、查询所有(包括有成绩和无成绩)SQL

select s.sid,s.sname,a.[选课总数],a.[总成绩]fromstudent
s leftjoin

(select sid,count(*)as
'
选课总数',sum(score)as
'
总成绩'from sc
group by sid) a

on s.sid=a.sid

 

select*
fromstudent s left
join

(select sid,count(cid)as
'
课程总数',sum(score)as
'
课程总成绩'from sc
group by sid) a

on s.sid=a.sidorderby
s.sid

 

select s.sid,s.sname,count(a.cid)as
'
课程总数',sum(a.score)as
'
课程总成绩'from student s
leftjoin sc a

on s.sid=a.sidgroupby
s.sid,s.snameorder
by s.sid

 

select a.Sid[学生编号],
a.Sname
[
学生姓名],count(b.Cid)
选课总数,sum(score)
[
所有课程的总成绩]

from Student aleftjoin SC b

on a.Sid= b.Sid

groupby a.Sid,a.Sname

orderby a.Sid

 

--6、查询""姓老师的数量

select count(*) as '数量' fromteacher where left(tname,1)=''

 

--方法1

selectcount(Tname)[""姓老师的数量]from
Teacher
where Tnamelike N'
%'

--方法2

selectcount(Tname)[""姓老师的数量]from
Teacher
whereleft(Tname,1)=
N
'
'

 

--7、查询学过"张三"老师授课的同学的信息

思路: STUDENT(一个记录集合),张三老师(一个记录集合),张三老师上的课(一个记录集合),张三老师上的课的成绩(一个记录集合)

select*
fromstudent s inner
joinsc a

on s.sid=a.sidinnerjoin
course c

on a.cid=c.cidinnerjoin
teacher t

on c.tid=t.tidwheret.tname='张三'

 

思路:从全部学生中(一个记录集合)提取上过张三老师课的学生(一个记录集合)

select*
fromstudent where sid
in(

select sidfrom sc a
inner join course b

on a.cid=b.cidinnerjoin
teacher c

on b.tid=c.tidandc.tname='张三')

 

selectdistinct Student.*from
Student , SC , Course , Teacher

where Student.Sid= SC.Sid
and SC.Cid
= Course.Cidand Course.Tid
= Teacher.Tid
and Teacher.Tname= N'
张三'

orderby Student.Sid

 

--8、查询没学过"张三"老师授课的同学的信息

思路:从全部学生中(一个记录集合)删除上过张三老师课的学生(一个记录集合)。

select*
fromstudent where sid
notin(
select distinct sid
from sc a inner
join
course c

on a.cid=c.cidinnerjoin
teacher t

on c.tid=t.tidwheret.tname='张三')

 

select m.*from Student mwhere
Sid
notin (selectdistinct SC.Sidfrom
SC , Course , Teacher
where SC.Cid
= Course.Cid
and Course.Tid= Teacher.Tid
and Teacher.Tname
= N'
张三')orderby
m.Sid

 

--9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息

思路:上过课程01(一个记录集合),上过课程02(一个记录集合),STUDENT表(一个记录集合)

select*
fromstudent s inner
joinsc a

on s.sid=a.sidanda.cid='01'inner
join sc b

on s.sid=b.sidandb.cid='02'

 

思路:上过课程01的学生(一个记录集合)并且存在上过课程02的学生(一个记录集合)

select*
fromstudent s inner
joinsc a

on s.sid=a.sidanda.cid='01'and
exists (select 1
from sc bwhere s.sid=b.sidand b.cid='02')

 

--方法1

select Student.*from Student , SCwhere
Student.Sid
= SC.Sid
and SC.Cid
='01'andexists (Select1from
SC SC_2
where SC_2.Sid= SC.Sid
and SC_2.Cid
='02')orderby Student.Sid

--方法2

select Student.*from Student , SCwhere
Student.Sid
= SC.Sid
and SC.Cid
='02'andexists (Select1from
SC SC_2
where SC_2.Sid= SC.Sid
and SC_2.Cid
='01')orderby Student.Sid

--方法3

select m.*from Student mwhere
Sid
in

(

 
select Sid from

 
(

   selectdistinctSidfrom
SC
where Cid='01'

   unionall

   selectdistinctSidfrom
SC
where Cid='02'

 
) t groupby Sidhavingcount(1)=2

)

orderby m.Sid

 

--10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息

思路:上过课程01的学生(一个记录集合)并且不存在上过课程02的学生(一个记录集合)

select*
fromstudent s inner
joinsc a

on s.sid=a.sidanda.cid='01'and
not exists
(
select 1from sc b
where s.sid=b.sidand b.cid='02')

 

思路:从全部学生中(一个记录集合)先提取上过课程01的学生记录(一个记录集合)再排除没上过课程02的学生记录(一个记录集合)

select*
fromstudent where sid
in

(select sidfrom sc
where cid='01')and sid
not in
(

select sidfrom sc
where cid='02')

 

select*
fromstudent s inner
joinsc a

on s.sid=a.sidanda.cid='01'where
s.sid not
in
(select sidfrom sc
where cid='02')

 

--方法1

select Student.*from Student , SCwhere
Student.Sid
= SC.Sid
and SC.Cid
='01'andnotexists (Select1from
SC SC_2
where SC_2.Sid
= SC.Sid
and SC_2.Cid='02')orderby
Student.Sid

--方法2

select Student.*from Student , SCwhere
Student.Sid
= SC.Sid
and SC.Cid
='01'and Student.Sidnotin (Select
SC_2.Sid
from SC SC_2
where SC_2.Sid
= SC.Sidand SC_2.Cid
='02')orderby Student.Sid

 

--11、查询没有学全所有课程的同学的信息

思路:从全部学生中(一个记录集合)提取在SC表中课程总数不是全部的学生(一个记录集合)

select*
fromstudent where sid
in

(select sidfrom

(select sid,count(*)as
abc from sc group
by sid havingcount(*)<(selectcount(*)
from course)) t)

该方法只列出有课程分数的学生,一个课程分数也没有的学生不存在第二个记录集合中。

 

思路:从全部学生中(一个记录集合)排除在SC表中有全部课程分数的学生(一个记录集合)

select*
fromstudent where sid
notin

(select sidfrom

(select sid,count(*)as
abc from sc group
by sid havingcount(*)=(selectcount(*)
from course)) t)

该方法还会列出一个课程分数都没有的学生。

 

--11.1

select Student.*

from Student , SC

where Student.Sid= SC.Sid

groupby Student.Sid , Student.Sname ,Student.Sage , Student.Ssexhavingcount(Cid)<
(
selectcount(Cid)from Course)

 

--11.2

select Student.*

from Studentleftjoin SC

on Student.Sid= SC.Sid

groupby Student.Sid , Student.Sname ,Student.Sage , Student.Ssexhavingcount(Cid)<
(
selectcount(Cid)from Course)

 

--12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息

思路:从全部学生中(一个记录集合)提取所学课程中至少有一门和学生01所学课程相同(一个记录集合)(也就是课程ID至少有一个存在于学生01的课程ID中)并排除学生01

select*
fromstudent where sid
in

(selectdistinct sid
from scwhere cid
in

(select cidfrom sc
where sid='01')and sid<>'01')

 

selectdistinct Student.*from
Student , SC
where Student.Sid= SC.Sid
and SC.Cid
in (select Cidfrom SC
where Sid='01')and Student.Sid
<>'01'

 

--13、查询和"01"号的同学学习的课程完全相同的其他同学的信息

思路:从全部学生中(一个记录集合)提取所学全部课程ID存在于学生01的课程ID中并且课程总数等于学生01的课程总数(一个记录集合)

select*
fromstudent where sid
in

(selectdistinct sid
from scwhere cid
in

(select cidfrom sc
where sid='01')and sid<>'01'group
by sid

havingcount(*)=(selectcount(*)
from sc where sid='01'))

 

select Student.*from Studentwhere
Sid
in

(selectdistinct SC.Sidfrom
SC
where Sid<>'01'and SC.Cidin
(
selectdistinct Cidfrom SC
where Sid='01')

groupby SC.Sidhavingcount(1)=
(
selectcount(1)from
SC
where Sid='01'))

 

--14、查询没学过"张三"老师讲授的任一门课程的学生姓名

思路:从全部学生中(一个记录集合)排除学过老师张三上过的课的学生(一个记录集合)(就是在SC表中有张三老师上过的课的分数)

select*
fromstudent where sid
notin

(selectdistinct a.sid
from sc a inner
join
course b

on a.cid=b.cidinnerjoin
teacher c

on b.tid=c.tidwherec.tname='张三')

 

select student.*from studentwhere
student.Sid
notin

(selectdistinct sc.Sidfrom
sc , course , teacher
where sc.Cid
= course.Cid
and course.Tid= teacher.Tid
and teacher.tname
= N'
张三')

orderby student.Sid

 

--15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

思路:全部学生(一个记录集合),两门及以上不及格课程(一个记录集合)

select*
fromstudent s inner
join

(select sid,count(*)as
'
不及格课程总数',convert(decimal(18,2),avg(score))as
'
平均分数'from sc
where score<60group
by sid having
count
(*)>=2) b

on s.sid=b.sid

 

select s.sid,s.sname,convert(decimal(5,2),avg(a.score))as
average fromstudent sinner
joinsc a

on s.sid=a.sidgroupby
s.sid,s.snamehaving s.sid
in

(select sidfrom

(select sid,count(*)as
times from sc where score<60
groupby sid
having
count(*)>=2) t)

 

select student.Sid ,student.sname ,cast(avg(score)asdecimal(18,2))
avg_score
from student , sc

where student.Sid= SC.Sid
and student.Sid
in (select Sidfrom SC
where score<60groupby
Sid
havingcount(1)>=2)

groupby student.Sid , student.sname

 

--16、检索"01"课程分数小于60,按分数降序排列的学生信息

思路:全部学生(一个记录集合),课程01分数小于60(一个记录集合)

select*
fromstudent s inner
joinsc a

on s.sid=a.sidwherecid='01'and
score<60 order
by
score desc

 

select*
fromstudent s inner
join(select*
from sc where cid='01'and score<60)
a

on s.sid=a.sidorderby
a.score

 

select student.* , sc.Cid , sc.scorefrom
student , sc

where student.Sid= SC.Sid
and sc.score
<60and sc.Cid='01'

orderby sc.scoredesc 

 

--17☆☆☆、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

思路:全部学生(一个记录集合),全部课程分数和平均分(一个记录集合),两个记录集合进行合并行转列(新的一个记录集合)

select s.sid,s.sname,max(case
b.cname when N'
语文'then a.score
else null
end
)as
'
语文',

                                              max(case b.cnamewhen
N'
数学'then a.score
else null
end
)as
'
数学',

                                              max(case b.cnamewhen
N'
英语'then a.score
else null
end
)as
'
英语',

                                              convert(decimal(18,2),avg(a.score))as
'
平均成绩'

from student sleft
join sc a

on s.sid=a.sidleftjoin
course b

on a.cid=b.cidgroupby
s.sid,s.sname

orderby [平均成绩]desc

 

--17.1 SQL 2000静态

select a.Sid学生编号 , a.Sname学生姓名
,

      max(case c.Cnamewhen
N
'
语文'then b.score
elsenullend)[
语文],

      max(case c.Cnamewhen
N
'
数学'then b.score
elsenullend)[
数学],

      max(case c.Cnamewhen
N
'
英语'then b.score
elsenullend)[
英语],

      cast(avg(b.score)asdecimal(18,2))平均分

from Student a

leftjoin SC bon a.Sid
= b.Sid

leftjoin Course con b.Cid
= c.Cid

groupby a.Sid , a.Sname

orderby平均分desc

 

--17.2 SQL 2000动态

declare@sqlnvarchar(4000)

set@sql='select a.Sid '+
N
'
学生编号'+' , a.Sname '+
N
'
学生姓名'

select@sql=@sql+',max(case
c.Cname when N'''
+Cname+''' then b.score else null end) ['+Cname+']'

from (selectdistinct Cnamefrom
Course)
as t

set@sql=@sql+' , cast(avg(b.score)
as decimal(18,2))'
+ N'
平均分'+'
from Student a left join SC b on a.Sid= b.Sid left join Course c on b.Cid = c.Cid

groupby a.Sid , a.Sname order by '+ N'平均分'+'
desc'

exec(@sql)

 

--17.3有关sql2005的动静态写法参见我的文章《普通行列转换(version 2.0)》或《普通行列转换(version
3.0)
》。

 

--18☆☆☆☆☆、查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率

--及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90

思路:SC表和COURSE表联合查询,每一个字段要求都可以看作是一个子查询,一个一个子查询单独做出来后,再拼接在一起。

select b.cid,b.cname,max(score)as
'
最高分',min(score)as
'
最低分',convert(decimal(5,2),avg(score))as
'
平均分',

convert(varchar,convert(decimal(5,2),convert(decimal(5,2),count(casewhen
a.score>=60then 1
else null
end
))/count(1)*100))+'%'as
'
及格率',

convert(varchar,convert(decimal(5,2),convert(decimal(5,2),count(casewhen
a.score>=70and a.score<80then 1
else null
end
))/count(1)*100))+'%'as
'
中等率',

convert(varchar,convert(decimal(5,2),convert(decimal(5,2),count(casewhen
a.score>=80and a.score<90then 1
else null
end
))/count(1)*100))+'%'as
'
优良率',

convert(varchar,convert(decimal(5,2),convert(decimal(5,2),count(casewhen
a.score>=90then 1
else null
end
))/count(1)*100))+'%'as
'
优秀率'

from sc ainner
join course bon a.cid=b.cidgroup
by b.cid,b.cname

 

--方法1

select 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 n

where m.Cid= n.Cid

groupby m.Cid , m.Cname

orderby m.Cid

--方法2

select m.Cid[课程编号],
m.Cname
[
课程名称],

 (selectmax(score)from
SC
where Cid= m.Cid)
[
最高分],

 
(selectmin(score)from SCwhere 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、按各科成绩进行排序,并显示排名

思路:利用over(partition by字段名order by
字段名)函数。

正常排序:123

select row_number()over(partitionby
cid order by cid,score
desc)as sort,*
from sc

合并重复不保留空缺:1123

select dense_rank()over(partitionby
cid order by cid,score
desc)as sort,*
from sc

合并重复保留空缺:113

select rank() over(partitionby cid order by cid,score desc) as sort,*
from sc

 

--19.1 sql 2000用子查询完成

--Score重复时保留名次空缺

select t.* , px=
(
selectcount(1)from
SC
where Cid= t.Cid
and score> t.score)
+1from sc torderby
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.2sql 2005rank,DENSE_RANK完成

--Score重复时保留名次空缺(rank完成)

select t.* , px=
rank()
over(partition
by cidorderby scoredesc)
from sc torderby t.Cid , px

--Score重复时合并名次(DENSE_RANK完成)

select t.* , px=
DENSE_RANK()
over(partition
by cidorderby scoredesc)
from sc torderby t.Cid , px

 

--20、查询学生的总成绩并进行排名

思路:所有学生的总成绩(一个记录集合),再使用函数进行排序。

select rank()over(orderby
sum(a.score)desc)
as ranking,s.sid,s.sname,sum(a.score)as
'
总成绩'from student s
innerjoin sc a

on s.sid=a.sidgroupby
s.sid,s.sname

这个查询只能查询到有成绩的7名学生。

 

select dense_rank()over(orderby
isnull(sum(a.score),0)desc)
as ranking,s.sid,s.sname,

isnull(sum(a.score),0)as
'
总成绩'

from student sleft
join sc a on s.sid=a.sidgroup
by s.sid,s.sname

用了leftjoin就可以查询到所有的8名学生了,包括没有成绩的1名学生。

 

--20.1查询学生的总成绩

select m.Sid[学生编号]
,

      m.Sname
[
学生姓名] ,

      isnull(sum(score),0)[总成绩]

from Student mleftjoin SC non
m.Sid
= n.Sid

groupby m.Sid , m.Sname

orderby[总成绩]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 non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t2where总成绩>
t1.
总成绩)+1from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(sum(score),0)[总成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t1

orderby px

 

select t1.* , px=
(
selectcount(distinct
总成绩)from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(sum(score),0)[总成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t2where总成绩>=
t1.
总成绩)from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(sum(score),0)[总成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t1

orderby px

 

--20.3查询学生的总成绩并进行排名,sql 2005rank,DENSE_RANK完成,分总分重复时保留名次空缺和不保留名次空缺两种。

select t.* , px=
rank()
over(orderby[
总成绩]desc)from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(sum(score),0)[总成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t

orderby px

 

select t.* , px=
DENSE_RANK()
over(orderby[
总成绩]desc)from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(sum(score),0)[总成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t

orderby px

 

--21、查询不同老师所教不同课程平均分从高到低显示

思路:不同老师所教不同课程的平均分(一个记录集合),再使用函数over(order by字段名)

select rank()over(orderby
convert(decimal(5,2),avg(score))desc)
as ranking,c.tid,c.tname,b.cid,b.cname,

convert(decimal(5,2),avg(score))as
'
平均分'from sc a

innerjoin course b
on a.cid=b.cidinner
join teacher con b.tid=c.tidgroup
by c.tid,c.tname,b.cid,b.cname

 

select m.Tid , m.Tname ,cast(avg(o.score)asdecimal(18,2))
avg_score

from Teacher m , Course n , SCo

where m.Tid= n.Tid
and n.Cid= o.Cid

groupby m.Tid , m.Tname

orderby avg_scoredesc

 

--22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩

思路:所有课程成绩的学生及课程信息(一个记录集合),再利用函数排序(一个记录集合),选择第2名和第3名的记录。

;with abc as

(select row_number() over(partition by a.cidorder by a.score
desc)as ranking,s.sid,s.sname,a.cid,b.cname,

a.score from student sinner
join sc a on s.sid=a.sidinner
join course b on a.cid=b.cid)

select
*
from abc where ranking in
(
2,3)

 

select
*
from

(select row_number() over(partition by a.cidorder by a.score
desc)as ranking,s.sid,s.sname,a.cid,b.cname,

a.score from student sinner
join sc a on s.sid=a.sidinner
join course b on a.cid=b.cid) t

where t.rankingin(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) mwhere 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 pxbetween2and3orderby
m.cid , m.px

 

--22.2 sql 2005rank,DENSE_RANK完成

--Score重复时保留名次空缺(rank完成)

select*from (select
t.
* , px
= rank() over(partitionby cid
orderby scoredesc)
from sc t) mwhere px
between2and3orderby
m.Cid , m.px

--Score重复时合并名次(DENSE_RANK完成)

select*from (select
t.
* , px
= DENSE_RANK() over(partitionby cid
orderby scoredesc)
from sc t) mwhere px
between2and3orderby
m.Cid , m.px

 

--23☆☆☆、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比

思路:SC表和COURSE表联合查询(一个记录集合),然后每个字段都看做是一个子查询,最后将这些子查询拼接起来。

select b.cidas
'
课程编号',b.cnameas
'
课程名称',

count(1)as'总人数',

count(casewhen a.score<60then
1 else null
end
) as
'
不及格人数',

convert(decimal(5,2),count(casewhen
a.score>=0and a.score<60then 1
else null
end
)*100/count(1))as
'
不及格率%',

count(casewhen a.score>=60and
a.score<70then 1
else null
end
) as
'
及格人数',

convert(decimal(5,2),count(casewhen
a.score>=60and a.score<70then 1
else null
end
)*100/count(1))as
'
及格率%',

count(casewhen a.score>=70and
a.score<85then 1
else null
end
) as
'
优良人数',

convert(decimal(5,2),count(casewhen
a.score>=70and a.score<85then 1
else null
end
)*100/count(1))as
'
优良率%',

count(casewhen a.score>=85then
1 else null
end
) as
'
优秀人数',

convert(decimal(5,2),count(casewhen
a.score>=85then 1
else null
end
)*100/count(1))as
'
优秀率%'

from sc ainner
join course bon a.cid=b.cidgroup
by b.cid,b.cname

以上方法为横向显示。

 

select b.cidas
'
课程编号',b.cnameas
'
课程名称',(casewhen score<60
then '0-59'

                                                                                                                                  when score>=60
and score<70
then
'60-69'

                                                                                                                                  when score>=70
and score<85
then
'70-85'

                                                                                                                                  else
'85-100' end)
as '
分数段',

count(1)as'人数',

convert(decimal(18,2),count(1)*100/(selectcount(1)from
sc where cid=b.cid))as
'
百分比'

from sc ainner
join course bon a.cid=b.cidgroup
by all b.cid,b.cname,(casewhen
score<60 then
'0-59'

                                                                                                                                  when score>=60
and score<70
then
'60-69'

                                                                                                                                  when score>=70
and score<85
then
'70-85'

                                                                                                                                  else
'85-100' end)

orderby b.cid,b.cname,'分数段'

以上方法为纵向显示,但为0的就不显示了。

 

--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.Cname

orderby Course.Cid

--纵向显示1(显示存在的分数段)

select m.Cid[课程编号]
, m.Cname
[
课程名称] ,分数段=
(

 
casewhenn.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 n

where m.Cid= n.Cid

groupby m.Cid , m.Cname , (

 
casewhenn.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
[
课程名称] ,分数段=
(

 
casewhenn.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 n

where m.Cid= n.Cid

groupbyall m.Cid , m.Cname , (

 
casewhenn.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<70)*100.0/
(
selectcount(1)from
SC
where Cid= m.Cid)
asdecimal(18,2))[
百分比(%)],

 
(selectcount(1)from
SC
where Cid= m.Cid
and score>=70and score<85)[70-85],

 
cast((selectcount(1)from
SC
where Cid= m.Cid
and score>=70and score<85)*100.0/
(
selectcount(1)from
SC
where Cid= m.Cid)
asdecimal(18,2))[
百分比(%)],

 (selectcount(1)from
SC
where Cid= m.Cid
and score>=85)[85-100],

 
cast((selectcount(1)from
SC
where Cid= m.Cid
and score>=85)*100.0/
(
selectcount(1)from
SC
where Cid= m.Cid)
asdecimal(18,2))[
百分比(%)]

from Course m

orderby m.Cid

--纵向显示1(显示存在的分数段)

select m.Cid[课程编号]
, m.Cname
[
课程名称] ,分数段=
(

 
casewhenn.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)
数量

 
cast(count(1)*100.0/
(
selectcount(1)from
sc
where Cid= m.Cid)
asdecimal(18,2))[
百分比(%)]

from Course m , sc n

where m.Cid= n.Cid

groupby m.Cid , m.Cname , (

 
casewhenn.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
[
课程名称] ,分数段=
(

 
casewhenn.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)
数量

 
cast(count(1)*100.0/
(
selectcount(1)from
sc
where Cid= m.Cid)
asdecimal(18,2))[
百分比(%)]

from Course m , sc n

where m.Cid= n.Cid

groupbyall m.Cid , m.Cname , (

 
casewhenn.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 ,分数段

 

--24、查询学生平均成绩及其名次

思路:所有学生的平均成绩(一个记录集合),再使用函数进行排序。

select s.sid,s.sname,row_number()over(orderby
avg(score)desc)
as ranking,convert(decimal(18,2),

avg(score))as
'
平均成绩'from student s
innerjoin sc a
on
s.sid=a.sidgroup
by s.sid,s.sname

只显示有成绩的学生。

 

select s.sid,s.sname,row_number()over(orderby
avg(score)desc)
as ranking,convert(decimal(18,2),

avg(score))as
'
平均成绩'from student s
leftjoin sc a
on
s.sid=a.sidgroup
by s.sid,s.sname

显示所有学生。

 

--24.1查询学生的平均成绩并进行排名,sql 2000用子查询完成,分平均成绩重复时保留名次空缺和不保留名次空缺两种。

select t1.* , px=
(
selectcount(1)from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(cast(avg(score)asdecimal(18,2)),0)[平均成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t2where平均成绩>
t1.
平均成绩)+1from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(cast(avg(score)asdecimal(18,2)),0)[平均成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t1

orderby px

 

select t1.* , px=
(
selectcount(distinct
平均成绩)from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(cast(avg(score)asdecimal(18,2)),0)[平均成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t2where平均成绩>=
t1.
平均成绩)from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(cast(avg(score)asdecimal(18,2)),0)[平均成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t1

orderby px

 

--24.2查询学生的平均成绩并进行排名,sql 2005rank,DENSE_RANK完成,分平均成绩重复时保留名次空缺和不保留名次空缺两种。

select t.* , px=
rank()
over(orderby[
平均成绩]desc)from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(cast(avg(score)asdecimal(18,2)),0)[平均成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t

orderby px

 

select t.* , px=
DENSE_RANK()
over(orderby[
平均成绩]desc)from

(

 
select m.Sid [
学生编号] ,

        m.Sname
[
学生姓名] ,

        isnull(cast(avg(score)asdecimal(18,2)),0)[平均成绩]

 
from Student m leftjoin SC non m.Sid=
n.Sid

 
groupby m.Sid, m.Sname

)t

orderby px

 

--25、查询各科成绩前三名的记录

思路:各学科成绩排序(一个记录集合),再取前3

select
*
from

(select row_number() over(partition by a.cidorder by a.score
desc)as ranking,

s.sid,s.sname,a.score from student sinnerjoin
sc a on s.sid=a.sid) t where rankingin
(1,2,3)

 

--25.1分数重复时保留名次空缺

select m.* , n.Cid , n.scorefrom
Student m, SC n
where m.Sid
= n.Sid and n.scorein

(selecttop3 scorefrom
sc
where Cid= n.Cid
orderby scoredesc)
orderby n.Cid , n.scoredesc

 

--25.2分数重复时不保留名次空缺,合并名次

--sql 2000用子查询实现

select*from (select
t.
* , px
= (selectcount(distinct score)from
SC
where Cid= t.Cid
and score>= t.score)
from sc t) m
where pxbetween1and3orderby
m.cid , m.px

--sql 2005DENSE_RANK实现

select*from (select
t.
* , px
= DENSE_RANK() over(partitionby cid
orderby scoredesc)
from sc t) mwhere px
between1and3orderby
m.Cid , m.px

 

--26、查询每门课程被选修的学生数

思路:每门课被选修的学生数(一个记录集合)。

select*
fromcourse a inner
join

(select cid,count(*)as
'
人数'from sc
group by cid) b

on a.cid=b.cid

 

select a.cid,a.cname,count(1)as
'
人数'from course a
innerjoin sc b

on a.cid=b.cidgroupby
a.cid,a.cname

 

select cid ,count(Sid)[学生数]from
sc
groupby Cid

 

--27、查询出只有两门课程的全部学生的学号和姓名

select Student.Sid ,Student.Sname

from Student , SC

where Student.Sid= SC.Sid

groupby Student.Sid , Student.Sname

havingcount(SC.Cid)=2

orderby Student.Sid

 

--28、查询男生、女生人数

思路:

select ssex,count(1)as'人数'from
student groupby ssex

 

selectcount(Ssex)as男生人数from
Student
where Ssex
= N'
'

selectcount(Ssex)as女生人数from
Student
where Ssex
= N'
'

selectsum(casewhen
Ssex
= N'
'then1else0end)[男生人数],sum(casewhen
Ssex
= N'
'then1else0end)[女生人数]from
student

selectcasewhen Ssex=
N
'
'then N'男生人数'else
N
'
女生人数'end[男女情况]
,
count(1)[
人数]from
student
groupbycasewhen Ssex=
N
'
'then N'男生人数'else
N
'
女生人数'end

 

--29、查询名字中含有""字的学生信息

select*
fromstudent where sname
like'%
%'

 

select*from studentwhere
sname
like N'%
%'

select*from studentwherecharindex(N''
, sname)
>0

 

--30、查询同名同性学生名单,并统计同名人数

思路:按照姓名字段进行GROUP BY,同时计算人数,只要大于1,就是同姓同名。

select sname,count(1)as
'
人数'from student
groupby sname
having
count(1)>1

 

select Sname[学生姓名],count(*)[人数]from
Student
groupby Snamehavingcount(*)>1

 

--31、查询1990年出生的学生名单(注:Student表中Sage列的类型是datetime)

select*
fromstudent where
datepart(year,sage)='1990'

 

select*from Studentwhereyear(sage)=1990

select*from Studentwheredatediff(yy,sage,'1990-01-01')=0

select*from Studentwheredatepart(yy,sage)=1990

select*from Studentwhereconvert(varchar(4),sage,120)='1990'

 

--32、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列

思路:每门课程的平均成绩(一个记录集合),再使用函数排序,排序时根据平均成绩、课程编号。

select row_number()over(orderby
convert(decimal(18,2),avg(a.score))desc,b.cid)as
'
排名',b.cid,b.cname,convert(decimal(18,2),avg(a.score))as
'
平均成绩'from sc a
inner join course b

on a.cid=b.cidgroupby
b.cid,b.cname

 

select m.Cid , m.Cname ,cast(avg(n.score)asdecimal(18,2))
avg_score

from Course m, SC n

where m.Cid= n.Cid   

groupby m.Cid , m.Cname

orderby avg_scoredesc, m.Cid
asc

 

--33、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩

select s.sid,s.sname,convert(decimal(18,2),avg(a.score))as
'
平均成绩'from student s
innerjoin sc a

on s.sid=a.sidgroupby
s.sid,s.snamehaving
avg(a.score)>=85

 

select a.Sid , a.Sname ,cast(avg(b.score)asdecimal(18,2))
avg_score

from Student a , sc b

where a.Sid= b.Sid

groupby a.Sid , a.Sname

havingcast(avg(b.score)asdecimal(18,2))>=85

orderby a.Sid

 

--34、查询课程名称为"数学",且分数低于60的学生姓名和分数

select s.sid,s.sname,b.cname,a.scorefrom
student sinnerjoin sc a

on s.sid=a.sidinnerjoin
course b

on a.cid=b.cid

where b.cname='数学'and
a.score<60

 

select sname , score

from Student , SC , Course

where SC.Sid= Student.Sid
and SC.Cid
= Course.Cidand Course.Cname= N'
数学'and
score
<60

 

--35、查询所有学生的课程及分数情况;

select s.sid,s.sname,b.cid,b.cname,a.score

from student sinner
join sc a on s.sid=a.sidinner
join course bon a.cid=b.cid

 

select Student.* , Course.Cname , SC.Cid ,SC.score 

from Student, SC , Course

where Student.Sid= SC.Sid
and SC.Cid
= Course.Cid

orderby Student.Sid , SC.Cid

 

--36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数;

select s.sid,s.sname,b.cid,b.cname,a.scorefrom
student sinnerjoin sc a

on s.sid=a.sidinnerjoin
course b

on a.cid=b.cid

where a.score>70

 

select Student.* , Course.Cname , SC.Cid ,SC.score 

from Student, SC , Course

where Student.Sid= SC.Sid
and SC.Cid
= Course.Cidand SC.score
>=70

orderby Student.Sid , SC.Cid

 

--37、查询不及格的课程

select s.sid,s.sname,b.cid,b.cname,a.scorefrom
student sinnerjoin sc a

on s.sid=a.sidinnerjoin
course b

on a.cid=b.cid

where a.score<60

 

select Student.* , Course.Cname , SC.Cid ,SC.score 

from Student, SC , Course

where Student.Sid= SC.Sid
and SC.Cid
= Course.Cidand SC.score
<60

orderby Student.Sid , SC.Cid

 

--38、查询课程编号为01且课程成绩在80分以上的学生的学号和姓名;

select s.sid,s.sname,b.cid,b.cname,a.scorefrom
student sinnerjoin sc a

on s.sid=a.sidinnerjoin
course b

on a.cid=b.cid

where a.score>=80and b.cid='01'

 

select Student.* , Course.Cname , SC.Cid ,SC.score 

from Student, SC , Course

where Student.Sid= SC.Sid
and SC.Cid
= Course.Cidand SC.Cid
='01'and SC.score>=80

orderby Student.Sid , SC.Cid

 

--39、求每门课程的学生人数

select b.cid,b.cname,count(1)as
'
人数'from sc a
inner join course b

on a.cid=b.cidgroupby
b.cid,b.cname

 

select Course.Cid , Course.Cname,count(*)[学生人数]

from Course , SC

where Course.Cid= SC.Cid

groupby Course.Cid , Course.Cname

orderby Course.Cid , Course.Cname

 

--40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩

思路:上张三老师课的学生(一个记录集合)

selecttop 1
* from student s
inner
join sc a

on s.sid=a.sidinnerjoin
course b

on a.cid=b.cidinnerjoin
teacher c

on b.tid=c.tidwherec.tname='张三'order
by a.scoredesc

 

--40.1当最高分只有一个时

selecttop1 Student.*
, Course.Cname , SC.Cid ,SC.score 

from Student, SC , Course ,Teacher

where Student.Sid= SC.Sid
and SC.Cid
= Course.Cidand Course.Tid
= Teacher.Tid
and Teacher.Tname= N'
张三'

orderby SC.scoredesc

 

--40.2当最高分出现多个时

select Student.* , Course.Cname , SC.Cid ,SC.score 

from Student, SC , Course ,Teacher

where Student.Sid= SC.Sid
and SC.Cid
= Course.Cidand Course.Tid
= Teacher.Tid
and Teacher.Tname= N'
张三'and

SC.score= (selectmax(SC.score)from
SC , Course , Teacher
where SC.Cid
= Course.Cid
and Course.Tid= Teacher.Tid
and Teacher.Tname
= N'
张三')

 

--41☆☆☆☆☆、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

思路:

 

 

--方法1

select m.*from SC m ,(select
Cid , score
from SCgroupby Cid , scorehavingcount(1)>1)
n

where m.Cid= n.Cidand
m.score
= n.score
orderby m.Cid , m.score , m.Sid

--方法2

select m.*from SC mwhereexists
(
select1from (select Cid , scorefrom
SC
groupby Cid , scorehavingcount(1)>1)
n

where m.Cid= n.Cidand
m.score
= n.score)
orderby m.Cid , m.score , m.Sid

 

--42、查询每门课程成绩最好的前两名

思路:每门课程全部成绩(一个记录集合)。

select
*
from (selectrow_number() over(partitionby cid order by score desc) as ranking,* from sc)
a whereranking in (1,2)

 

select t.*from sc twhere
score
in (selecttop2 scorefrom
sc
where Cid= T.Cid
orderby scoredesc)
orderby t.Cid , t.scoredesc

 

--43、统计每门课程的学生选修人数(超过5人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列 

select b.cid,b.cname,count(1)as
'
人数'from sc a
inner join course b

on a.cid=b.cidgroupby
b.cid,b.cnamehaving
count(1)>5order
by count(1)
desc,b.cid

 

select Course.Cid , Course.Cname,count(*)[学生人数]

from Course , SC

where Course.Cid= SC.Cid

groupby Course.Cid , Course.Cname

havingcount(*)>=5

orderby[学生人数]desc
, Course.Cid

 

--44、检索至少选修两门课程的学生学号

select s.sid,s.sname,count(1)as
'
课程数'from student s
innerjoin sc a

on s.sid=a.sidgroupby
s.sid,s.snamehaving
count(1)>=2

 

select student.Sid ,student.Sname

from student , SC

where student.Sid= SC.Sid

groupby student.Sid , student.Sname

havingcount(1)>=2

orderby student.Sid

 

--45、查询选修了全部课程的学生信息

select s.sid,s.sname,count(1)as
'
课程数'from student s
innerjoin sc a

on s.sid=a.sidgroupby
s.sid,s.snamehaving
count(1)>=(selectcount(1)from
course)

 

--方法1根据数量来完成

select student.*from studentwhere
Sid
in

(select Sidfrom sc
groupby Sidhavingcount(1)=
(
selectcount(1)from
course))

--方法2使用双重否定来完成

select t.*from student twhere
t.Sid
notin

(

 
selectdistinctm.Sidfrom

 
(

   select Sid , Cidfrom student , course

 
) m wherenotexists (select1from
sc n
where n.Sid= m.Sid
and n.Cid= m.Cid)

)

--方法3使用双重否定来完成

select t.*from student twherenotexists(select1from

(

 
selectdistinctm.Sidfrom

 
(

   select Sid , Cidfrom student , course

 
) m wherenotexists (select1from
sc n
where n.Sid= m.Sid
and n.Cid= m.Cid)

) kwhere k.Sid
= t.Sid

)

 

--46、查询各学生的年龄

select*,datediff(year,sage,getdate())as
'
年龄'from student

粗略算法

select*,datediff(day,sage,getdate())/365as
'
年龄'from student

具体算法

 

--46.1只按照年份来算

select* ,datediff(yy , sage ,getdate())
[
年龄]from student

 

--46.2按照出生日期来算,当前月日 <
出生年月的月日则,年龄减一

select* ,casewhenright(convert(varchar(10),getdate(),120),5)<right(convert(varchar(10),sage,120),5)thendatediff(yy
, sage ,
getdate())
-1elsedatediff(yy , sage ,getdate())
end[
年龄]from student

 

--47、查询本周过生日的学生

思路:将学生出生日期的年换成今年,然后加上具体日期,再和今天比较,如果为0,就是本周,如果为-1,就是下周,如果为1,就是上周。

select*
fromstudent

wheredatediff(week,convert(varchar,datepart(yy,getdate()))+right(convert(varchar(10),sage,120),6),getdate())=0

 

select*from studentwheredatediff(week,datename(yy,getdate())+right(convert(varchar(10),sage,120),6),getdate())=0

 

--48、查询下周过生日的学生

select*
fromstudent

wheredatediff(week,convert(varchar,datepart(yy,getdate()))+right(convert(varchar(10),sage,120),6),getdate())=-1

 

select*from studentwheredatediff(week,datename(yy,getdate())+right(convert(varchar(10),sage,120),6),getdate())=-1

 

--49、查询本月过生日的学生

思路:把学生的出生日期的年换成今年,然后判断月是否在当前月。为0就是本月,为1就是上月,为-1就是下月。

select*
fromstudent

wheredatediff(mm,convert(varchar,datepart(yy,getdate()))+right(convert(varchar(10),sage,120),6),getdate())=0

 

select*from studentwheredatediff(mm,datename(yy,getdate())+right(convert(varchar(10),sage,120),6),getdate())=0

 

--50、查询下月过生日的学生

select*
fromstudent

wheredatediff(mm,convert(varchar,datepart(yy,getdate()))+right(convert(varchar(10),sage,120),6),getdate())=-1

 

select*from studentwheredatediff(mm,datename(yy,getdate())+right(convert(varchar(10),sage,120),6),getdate())=-1

 

总结:

1.一种是先组合成一个总的记录集合,然后再进行GROUP BY或者ORDER
BY
等其他操作;另一种是分别先对小的记录集合进行其他操作,然后再组合到一起成为最终的一个记录集合。

2.针对排序,有三种情况:

RANK()OVER():排名113——保留

DENSE_RANK()OVER:排名112——不保留

ROW_NUMBEROVER():排名123——没有同排名的

3.有关日期的计算,一是要注意东西方对星期开始的差异,最好是使用SET DATEFIRST 1来人为的设定每周开始为星期一。二是要注意年、月、日三个元素的分别调整。三是要注意在调整过程中数据类型的变换。

 

 

【上篇】
【下篇】

抱歉!评论已关闭.