常用SQL语句有哪些

网友投稿 191 2023-11-29

常用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分数

*/

--创建测试数据

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=01inner

join sc c

on a.sid=c.sidandc.cid=02where

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=01inner

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=01and c.Cid=02and

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=01left

join sc b

on s.sid=b.sidand(b.cid=02or

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=01leftjoin 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=01inner

join sc b

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

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=01and c.Cid=02and

b.score< c.score

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

select*

fromstudent s left

joinsc a

on s.sid=a.sidand(a.cid=01or

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=01or 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 , Teacherwhere 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=01inner

join sc b

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

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

select*

fromstudent s inner

joinsc a

on s.sid=a.sidanda.cid=01and

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

=01andexists (Select1

from

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

=02andexists (Select1

from

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=01and

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=01where

s.sid not

in (select sidfrom sc

where cid=02)

--方法1

select Student.*from Student , SCwhere

Student.Sid= SC.Sid

and SC.Cid

=01andnotexists (Select1

from

SC SC_2where 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

=01and Student.Sidnotin (Select

SC_2.Sidfrom 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<>01group

by sid

havingcount(*)=(selectcount(*)

from sc where sid=01))

select Student.*from Studentwhere

Sid in

(selectdistinct SC.Sidfrom

SC where Sid<>01and 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.Sidnotin

(selectdistinct sc.Sidfrom

sc , course , teacherwhere 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<60

groupby

Sidhavingcount(1)>=2)

groupby student.Sid , student.sname

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

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

select*

fromstudent s inner

joinsc a

on s.sid=a.sidwherecid=01and

score<60 order

by score desc

select*

fromstudent s inner

join(select*

from sc where cid=01and 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-ame when N语文then a.score

else null

end)as

语文,

                                              max(case b-amewhen

N数学then a.score

else null

end)as

数学,

max(case b-amewhen

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-ame,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-ame

--方法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

字段名)函数。

正常排序:1,2,3

select row_number()over(partitionby

cid order by cid,score

desc)as sort,*

from sc

合并重复不保留空缺:1,1,2,3

select dense_rank()over(partitionby

cid order by cid,score

desc)as sort,*

from sc

合并重复保留空缺:1,1,3

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

from sc

--19.1sql 2000用子查询完成

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

select t.* , px=

(selectcount(1

)from

SC where Cid= t.Cid

and score> t.score)

+1

from 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 2005用rank,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 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 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-ame,

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-ame

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-ame,

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-ame,

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)

+1

from sc t) mwhere px

between2and3

orderby

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 pxbetween2and3

orderby

m.cid , m.px

--22.2 sql 2005用rank,DENSE_RANK完成

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

select*from (select

t.* , px

= rank() over(partitionby cid

orderby scoredesc)

from sc t) mwhere px

between2and3

orderby

m.Cid , m.px

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

select*from (select

t.* , px

= DENSE_RANK() over(partitionby cid

orderby scoredesc)

from sc t) mwhere px

between2and3

orderby

m.Cid , m.px

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

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

select b.cidas

课程编号,b-ameas

课程名称,

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-ame

以上方法为横向显示。

select b.cidas

课程编号,b-ameas

课程名称,(casewhen score<60

then 0-59

                                                                                                                                  when score>=60

and score<70

then60-69

                                                                                                                                  when score>=70

and score<85

then70-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-ame,(casewhen

score<60 then

0-59

when score>=60

and score<70

then60-69

                                                                                                                                  when score>=70

and score<85

then70-85

                                                                                                                                  else

85-100 end)

orderby b.cid,b-ame,分数段

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

--23.1统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]

--横向显示

select Course.Cid[课程编号]

, Cnameas[课程名称] ,

sum(casewhen score>=85then1else0end)[85-100],

sum(casewhen score>=70

and

score<85then1else0end)[70-85],

sum(casewhen score>=60

and

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>=85then85-100

when n.score

>=70and n.score<85then70-85

      when n.score

>=60and n.score<70then60-70

      else0-60

end) ,

count(1)数量

from Course m , sc n

where m.Cid= n.Cid

groupby m.Cid , m.Cname , (

casewhenn.score>=85then85-100

when n.score

>=70and n.score<85then70-85

      when n.score

>=60and n.score<70then60-70

      else0-60

end)

orderby m.Cid , m.Cname ,分数段

--纵向显示2(显示存在的分数段,不存在的分数段用0显示)

select m.Cid[课程编号]

, m.Cname[课程名称] ,分数段=

(

casewhenn.score>=85then85-100

      when n.score

>=70and n.score<85then70-85

      when n.score

>=60and n.score<70then60-70

      else0-60

end) ,

count(1)数量

from Course m , sc n

where m.Cid= n.Cid

groupbyall m.Cid , m.Cname , (

casewhenn.score>=85then85-100

      when n.score

>=70and n.score<85then70-85

      when n.score

>=60and n.score<70then60-70

      else0-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>=85then85-100

      when n.score

>=70and n.score<85then70-85

      when n.score

>=60and n.score<70then60-70

      else0-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>=85then85-100

      when n.score

>=70and n.score<85then70-85

      when n.score

>=60and n.score<70then60-70

else0-60

end)

orderby m.Cid , m.Cname ,分数段

--纵向显示2(显示存在的分数段,不存在的分数段用0显示)

select m.Cid[课程编号]

, m.Cname[课程名称] ,分数段=

(

casewhenn.score>=85then85-100

      when n.score

>=70and n.score<85then70-85

      when n.score

>=60and n.score<70then60-70

      else0-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>=85then85-100

      when n.score

>=70and n.score<85then70-85

      when n.score

>=60and n.score<70then60-70

else0-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 2005用rank,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 nwhere 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 pxbetween1and3

orderby

m.cid , m.px

--sql 2005用DENSE_RANK实现

select*from (select

t.* , px

= DENSE_RANK() over(partitionby cid

orderby scoredesc)

from sc t) mwhere px

between1and3

orderby

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-ame,count(1)as

人数from course a

innerjoin sc b

on a.cid=b.cidgroupby

a.cid,a-ame

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

Studentwhere Ssex

= N男

selectcount(Ssex)as女生人数from

Studentwhere Ssex

= N女

selectsum(casewhen

Ssex = N男then1else0

end)[男生人数],sum(casewhen

Ssex = N女then1else0

end)[女生人数]from

student

selectcasewhen Ssex=

N男then N男生人数else

N女生人数end[男女情况]

, count(1

)[人数]from

studentgroupbycasewhen 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

Studentgroupby 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-ame,convert(decimal(18,2),avg(a.score))as

平均成绩from sc a

inner join course b

on a.cid=b.cidgroupby

b.cid,b-ame

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-ame,a.scorefrom

student sinnerjoin sc a

on s.sid=a.sidinnerjoin

course b

on a.cid=b.cid

where b-ame=数学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-ame,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-ame,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-ame,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-ame,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

=01and SC.score>=80

orderby Student.Sid , SC.Cid

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

select b.cid,b-ame,count(1)as

人数from sc a

inner join course b

on a.cid=b.cidgroupby

b.cid,b-ame

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 , Teacherwhere 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

(select1

from (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-ame,count(1)as

人数from sc a

inner join course b

on a.cid=b.cidgroupby

b.cid,b-amehaving

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 (select1

from

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 (select1

from

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

-1

elsedatediff(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():排名1,1,3——保留

DENSE_RANK()OVER:排名1,1,2——不保留

ROW_NUMBEROVER():排名1,2,3——没有同排名的

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

关于“常用SQL语句有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:NoSQL的重要理论有哪些
下一篇:MSSQL怎么看各个ID对应具体DB的角色
相关文章

 发表评论

暂时没有评论,来抢沙发吧~