1案例描述:
从题库(保存了所有考试的题目)中抽出一样数量的题做为新的试卷,要求每次的试题顺序不同,
这样也就没法抄了啊。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
--建立表
create table Questions
( intQuestionID int,
vchQuestionText varchar(512)
)
go
create table TestQuestions
(intQuestionID int,
vchQuestionText varchar(512)
)
GO
--插入数据
declare @intCounter int
declare @vchQuestion varchar(64)
set nocount on
select @intCounter=1
while (@intCounter<=100)
begin
select @vchQuestion='Test Question #'+
Convert(varchar(8),@intCounter)
insert into Questions values(@intCounter,@vchQuestion)
select @intCounter=@intCounter+1
end
go
--准备查询语句,得到随机考题
declare @intQuestionid int
set nocount on
delete from TestQuestions
--rand() 返回0到1的随机数,
select @intQuestionid=ceiling(rand()*100) --返回1~100随机数
while(select count(*) from TestQuestions)<100
begin
while(select count(*) from TestQuestions
where intQuestionID=@intQuestionID)=1 --如果已经存在,则再次产生新随机数
begin
select @intQuestionid=ceiling(rand()*100)
end
insert into TestQuestions
select * from Questions
where intQuestionID=@intQuestionID
end
select * from Questions
select * from TestQuestions
create table Questions
( intQuestionID int,
vchQuestionText varchar(512)
)
go
create table TestQuestions
(intQuestionID int,
vchQuestionText varchar(512)
)
GO
--插入数据
declare @intCounter int
declare @vchQuestion varchar(64)
set nocount on
select @intCounter=1
while (@intCounter<=100)
begin
select @vchQuestion='Test Question #'+
Convert(varchar(8),@intCounter)
insert into Questions values(@intCounter,@vchQuestion)
select @intCounter=@intCounter+1
end
go
--准备查询语句,得到随机考题
declare @intQuestionid int
set nocount on
delete from TestQuestions
--rand() 返回0到1的随机数,
select @intQuestionid=ceiling(rand()*100) --返回1~100随机数
while(select count(*) from TestQuestions)<100
begin
while(select count(*) from TestQuestions
where intQuestionID=@intQuestionID)=1 --如果已经存在,则再次产生新随机数
begin
select @intQuestionid=ceiling(rand()*100)
end
insert into TestQuestions
select * from Questions
where intQuestionID=@intQuestionID
end
select * from Questions
select * from TestQuestions
2案例: 。关于学生,成绩,课程的查询
准备数据如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
--课程表
DROP TABLE [Course]
CREATE TABLE [Course] ( [C#] [int] NULL , [Cname] [varchar] (10) NULL , [T#] [int] NULL )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 1 , 'chinese' , 1 )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 2 , 'math' , 2 )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 3 , 'phy' , 3 )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 4 , 'art' , 1 )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 5 , 'english' , 3 )
--成绩表
DROP TABLE [SC]
CREATE TABLE [SC] ( [S#] [int] NULL , [C#] [int] NULL , [Score] [int] NULL )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 1 , 1 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 1 , 2 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 1 , 3 , 87 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 1 , 4 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 2 , 1 , 89 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 2 , 2 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 2 , 3 , 98 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 2 , 4 , 60 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 1 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 2 , 67 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 3 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 4 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 1 , 89 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 2 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 3 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 4 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 5 , 56 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 5 , 34 )
--学生表
DROP TABLE [Student]
CREATE TABLE [Student] ( [S#] [int] NULL , [Sname] [varchar] (10) NULL , [Sage] [int] NULL , [Ssex] [tinyint] NULL )
INSERT [Student] ( [S#] , [Sname] , [Sage] , [Ssex] ) VALUES ( 1 , 'Sname1' , 23 , 1 )
INSERT [Student] ( [S#] , [Sname] , [Sage] , [Ssex] ) VALUES ( 2 , 'Sname2' , 23 , 1 )
INSERT [Student] ( [S#] , [Sname] , [Sage] , [Ssex] ) VALUES ( 3 , 'Sname3' , 21 , 0 )
INSERT [Student] ( [S#] , [Sname] , [Sage] , [Ssex] ) VALUES ( 4 , 'Sname4' , 20 , 0 )
--教师表
DROP TABLE [Teacher]
CREATE TABLE [Teacher] ( [T#] [int] NULL , [Tname] [varchar] (10) NULL )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 1 , 'Sir Zhang' )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 2 , 'Miss Wang' )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 3 , 'Sir Li' )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 4 , 'Miss Li' )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 5 , 'Sir Duan' )
DROP TABLE [Course]
CREATE TABLE [Course] ( [C#] [int] NULL , [Cname] [varchar] (10) NULL , [T#] [int] NULL )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 1 , 'chinese' , 1 )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 2 , 'math' , 2 )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 3 , 'phy' , 3 )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 4 , 'art' , 1 )
INSERT [Course] ( [C#] , [Cname] , [T#] ) VALUES ( 5 , 'english' , 3 )
--成绩表
DROP TABLE [SC]
CREATE TABLE [SC] ( [S#] [int] NULL , [C#] [int] NULL , [Score] [int] NULL )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 1 , 1 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 1 , 2 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 1 , 3 , 87 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 1 , 4 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 2 , 1 , 89 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 2 , 2 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 2 , 3 , 98 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 2 , 4 , 60 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 1 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 2 , 67 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 3 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 4 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 1 , 89 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 2 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 3 , 90 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 4 , 78 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 4 , 5 , 56 )
INSERT [SC] ( [S#] , [C#] , [Score] ) VALUES ( 3 , 5 , 34 )
--学生表
DROP TABLE [Student]
CREATE TABLE [Student] ( [S#] [int] NULL , [Sname] [varchar] (10) NULL , [Sage] [int] NULL , [Ssex] [tinyint] NULL )
INSERT [Student] ( [S#] , [Sname] , [Sage] , [Ssex] ) VALUES ( 1 , 'Sname1' , 23 , 1 )
INSERT [Student] ( [S#] , [Sname] , [Sage] , [Ssex] ) VALUES ( 2 , 'Sname2' , 23 , 1 )
INSERT [Student] ( [S#] , [Sname] , [Sage] , [Ssex] ) VALUES ( 3 , 'Sname3' , 21 , 0 )
INSERT [Student] ( [S#] , [Sname] , [Sage] , [Ssex] ) VALUES ( 4 , 'Sname4' , 20 , 0 )
--教师表
DROP TABLE [Teacher]
CREATE TABLE [Teacher] ( [T#] [int] NULL , [Tname] [varchar] (10) NULL )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 1 , 'Sir Zhang' )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 2 , 'Miss Wang' )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 3 , 'Sir Li' )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 4 , 'Miss Li' )
INSERT [Teacher] ( [T#] , [Tname] ) VALUES ( 5 , 'Sir Duan' )
--1.查询“1”课程比“2”课程成绩高的所有学生的学号
select a.S# from
( select S#,score from sc where C#=1 ) a,
--得到两个基表
(select S#,score from sc where C#=2) b
where a.S#=b.S# and a.score>b.score
Select S#,Sname from (select Student.S#,Student.Sname,score ,
(select score from SC SC_2 where SC_2.S#=Student.S# and SC_2.C#='002') score2
from Student,SC where Student.S#=SC.S# and C#='001') S_2 where score2 <score;
--2、查询平均成绩大于60分的同学的学号和平均成绩;
select avg(score),S# from sc group by S#
having avg(score)>60
--3、查询所有同学的学号、姓名、选课数、总成绩;
select a.S#, a.sname, count(1),sum(b.score)
from student a,sc b
where a.S#=b.S# group by a.S# ,a.sname
-- a.s#已经完成分组了
--4、查询姓“Li”的老师的个数;
select count(1)
from teacher where Tname like '%Li'
--5、查询学过“Sir Li”老师课的同学的学号、姓名;
--li可能教多门课程
select Student.S#,Student.Sname
from Student
where S# in (select distinct( SC.S#) from SC,Course,Teacher where
SC.C#=Course.C# and Teacher.T#=Course.T# and Teacher.Tname='Sir Li');
select S#,Sname from student where S# in(
select distinct(S#)
--得到上sir li课的学生号
from sc join
(
select c.C# from teacher t,course c
where Tname='Sir Li' and t.T#=c.T#) b
--得到li 教的课程号
on sc.C#=b.C#
)
--两种方法思路一样,只是第一种是第二种的合并简化
--6、查询学过“1”并且也学过编号“2”课程的同学
---的学号、姓名;
select s#,sname from student
where s# in (
select S# from sc
--查询sc表,得到学习1,2课程的学生编号
where c#=1 or C#=2)
select Student.S#,Student.Sname from Student,SC where Student.S#=SC.S#
and SC.C#=1 --先满足条件课程 1 ,
and exists
( Select * from SC as SC_2 where SC_2.S#=SC.S# and SC_2.C#=2) --再满足条件2
--第一种效率更高 ,第二种方法是相关子查询,效率就低了
--7、查询学过Sir Li 老师所教的 所有课
-- 的同学的学号、姓名;
select student.s#
from student ,sc,
(select c.c#
from course c join teacher t
on c.T#=t.T#
where t.tname='Sir Li' ) a
where sc.c#=a.c# and student.s#=sc.s#
having count(sc.c#)=(select count(c#) from course,teacher
where teacher.tname='sir li' and teacher.t#=course.T#)
--- 首先这个语句得到的结果是错误的,因为这种全
--部的左连接是不符合题目中 ’全部‘两字的要求
select S#,Sname
from Student
where S# in (select S# from SC ,Course ,Teacher where SC.C#=Course.C# and
Teacher.T#=Course.T# and Teacher.Tname='Sir Li' group by S# having count(SC.C#)=(
select count(C#) from Course,Teacher where Teacher.T#=Course.T# and Tname='Sir Li'));
--些方法正确,思路:先得到上sir Li课程的全部学生,再---由having 添加条件
--8 查询课程编号“2”的成绩比课程编号“1”课程低的所有
--同学的学号、姓名;
select s#,sname from student where s# in (
select a.S# from
( select S#,score from sc where C#=1 ) a,
--得到两个基表
(select S#,score from sc where C#=2) b
where a.S#=b.S# and a.score>b.score)
---思路: 先得到 c#=1与C#=2的两个虚表,
-- 连接两个虚表 比较两个课程分数
Select S#,Sname ,c#,score2,score
from (
select Student.S#,Student.Sname,score ,c#,(
select score
from SC SC_2
where SC_2.S#=Student.S# and SC_2.C#=2) score2
from Student,SC
where Student.S#=SC.S# and C#=1
) S_2
where score2 <score;
---思路:我还没弄明白
-- 9、查询所有课程成绩小于60分的同学的学号、姓名;
select S#,Sname
from Student
where S# not in (select Student.S# from Student,SC where S.S#=SC.S# and score>60);
--10、查询没有学全所有课的同学的学号、姓名;
select Student.S#,Student.Sname
from Student,SC
where Student.S#=SC.S# group by Student.S#,Student.Sname having count(C#)
<(select count(C#) from Course);
select a.S# from
( select S#,score from sc where C#=1 ) a,
--得到两个基表
(select S#,score from sc where C#=2) b
where a.S#=b.S# and a.score>b.score
Select S#,Sname from (select Student.S#,Student.Sname,score ,
(select score from SC SC_2 where SC_2.S#=Student.S# and SC_2.C#='002') score2
from Student,SC where Student.S#=SC.S# and C#='001') S_2 where score2 <score;
--2、查询平均成绩大于60分的同学的学号和平均成绩;
select avg(score),S# from sc group by S#
having avg(score)>60
--3、查询所有同学的学号、姓名、选课数、总成绩;
select a.S#, a.sname, count(1),sum(b.score)
from student a,sc b
where a.S#=b.S# group by a.S# ,a.sname
-- a.s#已经完成分组了
--4、查询姓“Li”的老师的个数;
select count(1)
from teacher where Tname like '%Li'
--5、查询学过“Sir Li”老师课的同学的学号、姓名;
--li可能教多门课程
select Student.S#,Student.Sname
from Student
where S# in (select distinct( SC.S#) from SC,Course,Teacher where
SC.C#=Course.C# and Teacher.T#=Course.T# and Teacher.Tname='Sir Li');
select S#,Sname from student where S# in(
select distinct(S#)
--得到上sir li课的学生号
from sc join
(
select c.C# from teacher t,course c
where Tname='Sir Li' and t.T#=c.T#) b
--得到li 教的课程号
on sc.C#=b.C#
)
--两种方法思路一样,只是第一种是第二种的合并简化
--6、查询学过“1”并且也学过编号“2”课程的同学
---的学号、姓名;
select s#,sname from student
where s# in (
select S# from sc
--查询sc表,得到学习1,2课程的学生编号
where c#=1 or C#=2)
select Student.S#,Student.Sname from Student,SC where Student.S#=SC.S#
and SC.C#=1 --先满足条件课程 1 ,
and exists
( Select * from SC as SC_2 where SC_2.S#=SC.S# and SC_2.C#=2) --再满足条件2
--第一种效率更高 ,第二种方法是相关子查询,效率就低了
--7、查询学过Sir Li 老师所教的 所有课
-- 的同学的学号、姓名;
select student.s#
from student ,sc,
(select c.c#
from course c join teacher t
on c.T#=t.T#
where t.tname='Sir Li' ) a
where sc.c#=a.c# and student.s#=sc.s#
having count(sc.c#)=(select count(c#) from course,teacher
where teacher.tname='sir li' and teacher.t#=course.T#)
--- 首先这个语句得到的结果是错误的,因为这种全
--部的左连接是不符合题目中 ’全部‘两字的要求
select S#,Sname
from Student
where S# in (select S# from SC ,Course ,Teacher where SC.C#=Course.C# and
Teacher.T#=Course.T# and Teacher.Tname='Sir Li' group by S# having count(SC.C#)=(
select count(C#) from Course,Teacher where Teacher.T#=Course.T# and Tname='Sir Li'));
--些方法正确,思路:先得到上sir Li课程的全部学生,再---由having 添加条件
--8 查询课程编号“2”的成绩比课程编号“1”课程低的所有
--同学的学号、姓名;
select s#,sname from student where s# in (
select a.S# from
( select S#,score from sc where C#=1 ) a,
--得到两个基表
(select S#,score from sc where C#=2) b
where a.S#=b.S# and a.score>b.score)
---思路: 先得到 c#=1与C#=2的两个虚表,
-- 连接两个虚表 比较两个课程分数
Select S#,Sname ,c#,score2,score
from (
select Student.S#,Student.Sname,score ,c#,(
select score
from SC SC_2
where SC_2.S#=Student.S# and SC_2.C#=2) score2
from Student,SC
where Student.S#=SC.S# and C#=1
) S_2
where score2 <score;
---思路:我还没弄明白
-- 9、查询所有课程成绩小于60分的同学的学号、姓名;
select S#,Sname
from Student
where S# not in (select Student.S# from Student,SC where S.S#=SC.S# and score>60);
--10、查询没有学全所有课的同学的学号、姓名;
select Student.S#,Student.Sname
from Student,SC
where Student.S#=SC.S# group by Student.S#,Student.Sname having count(C#)
<(select count(C#) from Course);
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
--11、查询至少有一门课与学号为 4 的
--同学所学相同的同学的学号和姓名;
select distinct student.s#,sname
from student left join sc
on student.s#=sc.s# and c# in
(
select c# from sc where s#=4
)
select s#,sname
from student where
s# in
( select SC.S#
from Student,SC
where Student.S#=SC.S# and C# in (select C# from SC where S#=4)
)
--思路:先查到学号4同学的课程
--14、查询和3 号的同学学习的课程完全相同的其
--他同学学号和姓名;
select s#,a.c# from
(select c# from sc where s#=1 ) b
left join
(select s.s#,sc.c# from
sc,student s
where sc.s#=s.s#
) a
on a.c#=b.c#
group by s# having count(a.c#)=2 (
select count(c#) from sc where s#=1 )
--这个方法是错误的,
--错误思路:查询到所有学生的课程,然后与1同学的
--课程连接,然后having条件限制 ,
---------------
select S# from SC where C# in (select C# from SC where S#=3)
group by S# having count(*)=(select count(*) from SC where S#=3);
---方法二正确 ,用in 而不用连接
--17、按平均成绩从高到低显示所有学生的“数据库”、
--“企业管理”、“英语”三门的课程成绩,按如下形式
--显示: 学生ID,,数据库,企业管理,英语,有效课程数,
--有效平均分
SELECT S# as 学生ID
,(SELECT score FROM SC WHERE SC.S#=t.S# AND C#='004') AS 数据库
,(SELECT score FROM SC WHERE SC.S#=t.S# AND C#='001') AS 企业管理
,(SELECT score FROM SC WHERE SC.S#=t.S# AND C#='006') AS 英语
,COUNT(*) AS 有效课程数, AVG(t.score) AS 平均成绩
FROM SC AS t
GROUP BY S#
ORDER BY avg(t.score)
--19、按各科平均成绩从低到高和及格率的百分数从高到
--低顺序
SELECT t.C# AS 课程号,max(course.Cname)AS 课程名,isnull(AVG(score),0) AS 平均成绩
,100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数
, SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数
--因为/count(*)得到的是小数,但是在sql中保存为
--整数即0,所以要在前面*100
FROM SC T,Course
where t.C#=course.C#
GROUP BY t.C#
ORDER BY 100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) DESC
--20、查询如下课程平均成绩和及格率的百分数
--(用"1行"显示): 企业管理(1),马克思(2)
--,OO&UML (3),数据库(4)
select
sum(case when c#=1 then score else 0 end)/sum(case when c#=1 then 1 else 0 end) as '1课程平均分',
100*sum(case when c#=1 and score>=60 then 1 else 0 end)/sum(case when c#=1 then 1 else 0 end) as '1课程及格百分数'
,sum(case when c#=2 then score else 0 end)/sum(case when c#=2 then 1 else 0 end) as '2课程平均分',
100*sum(case when c#=2 and score>=60 then 1 else 0 end)/sum(case when c#=2 then 1 else 0 end) as '2课程及格百分数'
,sum(case when c#=3 then score else 0 end)/sum(case when c#=3 then 1 else 0 end) as '3课程平均分',
100*sum(case when c#=3 and score>=60 then 1 else 0 end)/sum(case when c#=3 then 1 else 0 end) as '3课程及格百分数'
,sum(case when c#=4 then score else 0 end)/sum(case when c#=4 then 1 else 0 end) as '4课程平均分',
100*sum(case when c#=4 and score>=60 then 1 else 0 end)/sum(case when c#=4 then 1 else 0 end) as '4课程及格百分数'
from sc
--在case中 也可以应用条件 and
--21 查询不同老师所教不同课程平均分从高到低显示
select max(c.t#) as '教师编号', max(c.tname) as '老师姓名',
a.c# as '课程编号', max(b.cname) as '课程名称',avg(score) as '平均成绩',
a.c#
from sc a,course b ,teacher c
where a.c#=b.C# and b.t#=c.T# group by a.c#
--,c.t# 本来应按照老师,课程分组的,但是注意
--这里对课程分组后
--也就对老师分组了,因为一个课程只能被一个老师任职
--思路分析 为了得到'老师编号’,
--‘老师姓名'等字段,对其做了聚合函数的处理
--23 统计各课程中各分数段的人数 显示如下:课程ID,
--课程名称,[100-85],[85-70],[70-60],[ <60]
select sc.c#,a.cname ,
sum(case when score between 85 and 100 then 1 else 0 end ) as '[100-85]',
SUM(CASE WHEN score BETWEEN 70 AND 85 THEN 1 ELSE 0 END) AS [85 - 70] ,
SUM(CASE WHEN score BETWEEN 60 AND 70 THEN 1 ELSE 0 END) AS [70 - 60] ,
SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS [60 -]
from sc,course a
where sc.c#=a.c#
group by sc.c# ,a.cname
--思路: case可以对行进行统计,产生列效果
--24 查询学生平均成绩及其名次
SELECT 1+(SELECT COUNT( distinct 平均成绩)
FROM (SELECT S#,AVG(score) AS 平均成绩 FROM SC GROUP BY S# ) AS T1 ---内层的子查询
WHERE 平均成绩 > T2.平均成绩) as 名次, S# as 学生学号,平均成绩
FROM (SELECT S#,AVG(score) 平均成绩
FROM SC
GROUP BY S#
) AS T2 --外层查询,t2为内层子查询提供条件
ORDER BY 平均成绩 desc;
--思路分析: 内层子查询在这里产生了新一列,
-- 是相关子查
View Code
询
--同学所学相同的同学的学号和姓名;
select distinct student.s#,sname
from student left join sc
on student.s#=sc.s# and c# in
(
select c# from sc where s#=4
)
select s#,sname
from student where
s# in
( select SC.S#
from Student,SC
where Student.S#=SC.S# and C# in (select C# from SC where S#=4)
)
--思路:先查到学号4同学的课程
--14、查询和3 号的同学学习的课程完全相同的其
--他同学学号和姓名;
select s#,a.c# from
(select c# from sc where s#=1 ) b
left join
(select s.s#,sc.c# from
sc,student s
where sc.s#=s.s#
) a
on a.c#=b.c#
group by s# having count(a.c#)=2 (
select count(c#) from sc where s#=1 )
--这个方法是错误的,
--错误思路:查询到所有学生的课程,然后与1同学的
--课程连接,然后having条件限制 ,
---------------
select S# from SC where C# in (select C# from SC where S#=3)
group by S# having count(*)=(select count(*) from SC where S#=3);
---方法二正确 ,用in 而不用连接
--17、按平均成绩从高到低显示所有学生的“数据库”、
--“企业管理”、“英语”三门的课程成绩,按如下形式
--显示: 学生ID,,数据库,企业管理,英语,有效课程数,
--有效平均分
SELECT S# as 学生ID
,(SELECT score FROM SC WHERE SC.S#=t.S# AND C#='004') AS 数据库
,(SELECT score FROM SC WHERE SC.S#=t.S# AND C#='001') AS 企业管理
,(SELECT score FROM SC WHERE SC.S#=t.S# AND C#='006') AS 英语
,COUNT(*) AS 有效课程数, AVG(t.score) AS 平均成绩
FROM SC AS t
GROUP BY S#
ORDER BY avg(t.score)
--19、按各科平均成绩从低到高和及格率的百分数从高到
--低顺序
SELECT t.C# AS 课程号,max(course.Cname)AS 课程名,isnull(AVG(score),0) AS 平均成绩
,100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数
, SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数
--因为/count(*)得到的是小数,但是在sql中保存为
--整数即0,所以要在前面*100
FROM SC T,Course
where t.C#=course.C#
GROUP BY t.C#
ORDER BY 100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) DESC
--20、查询如下课程平均成绩和及格率的百分数
--(用"1行"显示): 企业管理(1),马克思(2)
--,OO&UML (3),数据库(4)
select
sum(case when c#=1 then score else 0 end)/sum(case when c#=1 then 1 else 0 end) as '1课程平均分',
100*sum(case when c#=1 and score>=60 then 1 else 0 end)/sum(case when c#=1 then 1 else 0 end) as '1课程及格百分数'
,sum(case when c#=2 then score else 0 end)/sum(case when c#=2 then 1 else 0 end) as '2课程平均分',
100*sum(case when c#=2 and score>=60 then 1 else 0 end)/sum(case when c#=2 then 1 else 0 end) as '2课程及格百分数'
,sum(case when c#=3 then score else 0 end)/sum(case when c#=3 then 1 else 0 end) as '3课程平均分',
100*sum(case when c#=3 and score>=60 then 1 else 0 end)/sum(case when c#=3 then 1 else 0 end) as '3课程及格百分数'
,sum(case when c#=4 then score else 0 end)/sum(case when c#=4 then 1 else 0 end) as '4课程平均分',
100*sum(case when c#=4 and score>=60 then 1 else 0 end)/sum(case when c#=4 then 1 else 0 end) as '4课程及格百分数'
from sc
--在case中 也可以应用条件 and
--21 查询不同老师所教不同课程平均分从高到低显示
select max(c.t#) as '教师编号', max(c.tname) as '老师姓名',
a.c# as '课程编号', max(b.cname) as '课程名称',avg(score) as '平均成绩',
a.c#
from sc a,course b ,teacher c
where a.c#=b.C# and b.t#=c.T# group by a.c#
--,c.t# 本来应按照老师,课程分组的,但是注意
--这里对课程分组后
--也就对老师分组了,因为一个课程只能被一个老师任职
--思路分析 为了得到'老师编号’,
--‘老师姓名'等字段,对其做了聚合函数的处理
--23 统计各课程中各分数段的人数 显示如下:课程ID,
--课程名称,[100-85],[85-70],[70-60],[ <60]
select sc.c#,a.cname ,
sum(case when score between 85 and 100 then 1 else 0 end ) as '[100-85]',
SUM(CASE WHEN score BETWEEN 70 AND 85 THEN 1 ELSE 0 END) AS [85 - 70] ,
SUM(CASE WHEN score BETWEEN 60 AND 70 THEN 1 ELSE 0 END) AS [70 - 60] ,
SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS [60 -]
from sc,course a
where sc.c#=a.c#
group by sc.c# ,a.cname
--思路: case可以对行进行统计,产生列效果
--24 查询学生平均成绩及其名次
SELECT 1+(SELECT COUNT( distinct 平均成绩)
FROM (SELECT S#,AVG(score) AS 平均成绩 FROM SC GROUP BY S# ) AS T1 ---内层的子查询
WHERE 平均成绩 > T2.平均成绩) as 名次, S# as 学生学号,平均成绩
FROM (SELECT S#,AVG(score) 平均成绩
FROM SC
GROUP BY S#
) AS T2 --外层查询,t2为内层子查询提供条件
ORDER BY 平均成绩 desc;
--思路分析: 内层子查询在这里产生了新一列,
-- 是相关子查
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
--25、查询各科成绩前三名的记录:(不考虑成绩并列情况)
SELECT t1.S# as 学生ID,t1.C# as 课程ID,Score as 分数
FROM SC t1
WHERE score IN (SELECT TOP 3 score
FROM SC
WHERE t1.C#= C#
ORDER BY score DESC
)
ORDER BY t1.C#,分数
--思路分析:相关子查询, 你的思路错在:
--想要用group by c#,但是group by必然与聚合函数相关,
--但是这里需要的不是sum,count之类的聚合而是top 3,
--没有聚合计算的要求
--27 查询出只选修了一门课程的全部学生的学号和姓名
select sc.s#,student.sname,count(c#) as 选课数
from sc,student
where sc.s#=student.s# group by sc.s# ,student.sname having count(c#)=1
--28、查询男生、女生人数
select sum(case ssex when 1 then 1 else 0 end) '男生',
sum(case ssex when 0 then 1 else 0 end) '女生' from student
-- 40、查询选修 sir li 老师所授课程的学生中,
--成绩最高的学生姓名及其成绩
select Student.Sname,score
from Student,SC,Course C,Teacher
where Student.S#=SC.S# and SC.C#=C.C# and C.T#=Teacher.T# and Teacher.Tname='sir li' and SC.score=(select max(score)from SC where C#=C.C# );
--注意分析:sir li并不只教了一门课,所以用
--了相关子查询
--46、查询全部学生都选修的课程的课程号和课程名
select c#,cname from
course
where c# in (
select c#
from sc
group by c#
having count(c#)=(select count(1) from student)
)
SELECT t1.S# as 学生ID,t1.C# as 课程ID,Score as 分数
FROM SC t1
WHERE score IN (SELECT TOP 3 score
FROM SC
WHERE t1.C#= C#
ORDER BY score DESC
)
ORDER BY t1.C#,分数
--思路分析:相关子查询, 你的思路错在:
--想要用group by c#,但是group by必然与聚合函数相关,
--但是这里需要的不是sum,count之类的聚合而是top 3,
--没有聚合计算的要求
--27 查询出只选修了一门课程的全部学生的学号和姓名
select sc.s#,student.sname,count(c#) as 选课数
from sc,student
where sc.s#=student.s# group by sc.s# ,student.sname having count(c#)=1
--28、查询男生、女生人数
select sum(case ssex when 1 then 1 else 0 end) '男生',
sum(case ssex when 0 then 1 else 0 end) '女生' from student
-- 40、查询选修 sir li 老师所授课程的学生中,
--成绩最高的学生姓名及其成绩
select Student.Sname,score
from Student,SC,Course C,Teacher
where Student.S#=SC.S# and SC.C#=C.C# and C.T#=Teacher.T# and Teacher.Tname='sir li' and SC.score=(select max(score)from SC where C#=C.C# );
--注意分析:sir li并不只教了一门课,所以用
--了相关子查询
--46、查询全部学生都选修的课程的课程号和课程名
select c#,cname from
course
where c# in (
select c#
from sc
group by c#
having count(c#)=(select count(1) from student)
)