您的位置:首页 > 数据库

用SQL语句操作数据(库)表:如增,删,改,查

2016-06-10 20:31 393 查看
SQL语句的的while 循环

declare @i int,@j int

set @i=1

while @i<=(select count(s.sno) from student s)

begin

 (select COUNT(sc.score) as result from sc where sc.score>60 and sc.sno=@i)

  set @i=@i+1

 end

--1、查询课程1的成绩 比 课程2的成绩 高 的所有学生的学号.

select a.sno from

(select sno,score from sc where cno=1) a,

(select sno,score from sc where cno=2) b

where a.score>b.score and a.sno=b.sno

--2、查询平均成绩大于60分的同学的学号和平均成绩;

select sno,avg(score) as sscore from sc group by sno having avg(score) >60

--select a.sno as "学号", avg(a.score) as "平均成绩" 

--from

--(select sno,score from sc) a 

--group by sno having avg(a.score)>60

但是写成这样就会出错:语法没错

--select a.sno as "学号", avg(a.score) as "平均成绩" 

--from

--(select sno,score from sc) a 

--where avg(a.score)>60


////注意:group by 语句的作用

合计函数 (比如 SUM) 常常需要添加 GROUP BY 语句。  GROUP BY 语句  GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组。  SQL GROUP BY 语法  SELECT
column_name, aggregate_function(column_name)FROM table_nameWHERE column_name operator valueGROUP BY column_name


实例

  我们拥有下面这个 "Orders" 表:  
O_IdOrderDateOrderPriceCustomer
12008/12/291000Bush
22008/11/231600Carter
32008/10/05700Bush
42008/09/28300Bush
52008/08/062000Adams
62008/07/21100Carter
现在,我们希望查找每个客户的总金额(总订单)。  我们想要使用 GROUP BY 语句对客户进行组合。  我们使用下列 SQL 语句:  SELECT Customer,SUM(OrderPrice) FROM OrdersGROUP BY Customer结果集类似这样:  
CustomerSUM(OrderPrice)
Bush2000
Carter1700
Adams2000
SELECT Customer,SUM(OrderPrice) FROM Orders  结果集类似这样:  
CustomerSUM(OrderPrice)
Bush5700
Carter5700
Bush5700
Bush5700
Adams5700
Carter5700
上面的结果集不是我们需要的。  那么为什么不能使用上面这条 SELECT 语句呢?解释如下:上面的 SELECT 语句指定了两列(Customer 和 SUM(OrderPrice))。"SUM(OrderPrice)" 返回一个单独的值("OrderPrice" 列的总计),而 "Customer" 返回 6 个值(每个值对应 "Orders"
表中的每一行)。因此,我们得不到正确的结果。不过,您已经看到了,GROUP BY 语句解决了这个问题。


列表

  我们也可以对一个以上的列应用 GROUP BY 语句,就像这样:  SELECT Customer,OrderDate,SUM(OrderPrice) FROM OrdersGROUP BY Customer,OrderDate  特别注意:  group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在
group by 后面。

注意SQL 中where 和having子句的区别:

group by

 

    在select 语句中可以使用group by 子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集。group by 子句可以将查询结果分组,并返回行的汇总信息Oracle 按照group by 子句中指定的表达式的值分组查询结果。

   在带有group by 子句的查询语句中,在select 列表中指定的列要么是group by 子句中指定的列,要么包含聚组函数

   select max(sal),job emp group by job;

   (注意max(sal),job的job并非一定要出现,但有意义)

   查询语句的select 和group by ,having 子句是聚组函数唯一出现的地方,在where 子句中不能使用聚组函数。

  select deptno,sum(sal) from emp where sal>1200 group by deptno having sum(sal)>8500 order by deptno;

  当在gropu by 子句中使用having 子句时,查询结果中只返回满足having条件的组。在一个sql语句中可以有where子句和having子句。having 与where 子句类似,均用于设置限定条件

 

  where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。

  having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。

  查询每个部门的每种职位的雇员数

  select deptno,job,count(*) from emp group by deptno,job;

 

  如果你对何时应该使用WHERE,何时使用HAVING仍旧很迷惑,请遵照下面的说明:  

  WHERE语句在GROUP BY语句之前;SQL会在分组之前计算WHERE语句。  

  HAVING语句在GROUP BY语句之后;SQL会在分组之后计算HAVING语句。

--3、查询所有同学的学号、姓名、选课数、总成绩

select a.sno as 学号, b.sname as 姓名,

count(a.cno) as 选课数, sum(a.score) as 总成绩

from sc a, student b

where a.sno = b.sno

group by a.sno, b.sname

go

--3、查询所有同学的学号、姓名、选课数、总成绩

select student.sno as 学号, student.sname as 姓名,

 count(sc.cno) as 选课数, sum(score) as 总成绩

from student left Outer join sc on student.sno = sc.sno

group by student.sno, sname

、、、、、、、、、、、、、、、、、、、、、、、、、、、、

注意:SQL 中 left  outer join ,right out join ,inner join 区别:、、

   这两天,在研究SQL语法中的inner join多表查询语法的用法,通过学习,发现一个SQL命令,竟然涉及到很多线性代数方面的知识,现将这些知识系统地记录如下:

      使用关系代数合并数据

1 关系代数

合并数据集合的理论基础是关系代数,它是由E.F.Codd于1970年提出的。

在关系代数的形式化语言中:

?          用表、或者数据集合表示关系或者实体。

?          用行表示元组。

?          用列表示属性。

关系代数包含以下8个关系运算符

?          选取――返回满足指定条件的行。

?          投影――从数据集合中返回指定的列。

?          笛卡尔积――是关系的乘法,它将分别来自两个数据集合中的行以所有可能的方式进行组合。

?          并――关系的加法和减法,它可以在行的方向上合并两个表中的数据,就像把一个表垒在另一个表之上一样。

?          交――返回两个数据集合所共有的行。

?          差――返回只属于一个数据集合的行。

?          连接――在水平方向上合并两个表,其方法是:将两个表中在共同数据项上相互匹配的那些行合并起来。

?          除――返回两个数据集之间的精确匹配。

此外,作为一种实现现代关系代数运算的方法,SQL还提供了:

?          子查询――类似于连接,但更灵活;在外部查询中,方式可以使用表达式、列表或者数据集合的地方都可以使用子查询的结果。

本章将主要讲述多种类型的连接、简单的和相关的子查询、几种类型的并、关系除以及其他的内容。

2 使用连接

2.1 连接类型

在关系代数中,连接运算是由一个笛卡尔积运算和一个选取运算构成的。首先用笛卡尔积完成对两个数据集合的乘运算,然后对生成的结果集合进行选取运算,确保只把分别来自两个数据集合并且具有重叠部分的行合并在一起。连接的全部意义在于在水平方向上合并两个数据集合(通常是表),并产生一个新的结果集合,其方法是将一个数据源中的行于另一个数据源中和它匹配的行组合成一个新元组。

SQL提供了多种类型的连接方式,它们之间的区别在于:从相互交叠的不同数据集合中选择用于连接的行时所采用的方法不同。

连接类型          定义

内连接          只连接匹配的行

左外连接          包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行

右外连接          包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行

全外连接          包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。

(H)(theta)连接          使用等值以外的条件来匹配左、右两个表中的行

交叉连接          生成笛卡尔积-它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行都一一匹配

在INFORMIX中连接表的查询

如果FROM子句指定了多于一个表引用,则查询会连接来自多个表的行。连接条件指定各列之间(每个表至少一列)进行连接的关系。因为正在比较连接条件中的列,所以它们必须具有一致的数据类型。

SELECT语句的FROM子句可以指定以下几种类型的连接

FROM子句关键字          相应的结果集

CROSS JOIN          笛卡尔乘积(所有可能的行对)

INNER JOIN          仅对满足连接条件的CROSS中的列
LEFT OUTER JOIN          一个表满足条件的行,和另一个表的所有行

RIGHT OUTER JOIN          与LEFT相同,但两个表的角色互换

FULL OUTER JOIN        LEFT OUTER 和 RIGHTOUTER中所有行的超集

2.2 内连接(Inner Join)

内连接是最常见的一种连接,它页被称为普通连接,而E.FCodd最早称之为自然连接。

下面是ANSI SQL-92标准

select * 

from    t_institution i 

inner join t_teller t

on i.inst_no = t.inst_no

where i.inst_no = "5801"

其中inner可以省略。

等价于早期的连接语法

select * 

from t_institution i, t_teller t 

where i.inst_no = t.inst_no

and i.inst_no = "5801"

2.3 外连接

2.3.1          左外连接(Left Outer Jion)

select * 

from    t_institution i 
left outer join t_teller t

on i.inst_no = t.inst_no

其中outer可以省略。

2.3.2          右外连接(Rigt Outer Jion)

select * 

from    t_institution i 

right outer join t_teller t

on i.inst_no = t.inst_no

2.3.3          全外连接(Full Outer)

全外连接返回参与连接的两个数据集合中的全部数据,无论它们是否具有与之相匹配的行。在功能上,它等价于对这两个数据集合分别进行左外连接和右外连接,然后再使用消去重复行的并操作将上述两个结果集合并为一个结果集。

在现实生活中,参照完整性约束可以减少对于全外连接的使用,一般情况下左外连接就足够了。在数据库中没有利用清晰、规范的约束来防范错误数据情况下,全外连接就变得非常有用了,你可以使用它来清理数据库中的数据。

select * 

from    t_institution i 

full outer join t_teller t

on i.inst_no = t.inst_no

2.3.4          外连接与条件配合使用

当在内连接查询中加入条件是,无论是将它加入到join子句,还是加入到where子句,其效果是完全一样的,但对于外连接情况就不同了。当把条件加入到join子句时,SQL Server、Informix会返回外连接表的全部行,然后使用指定的条件返回第二个表的行。如果将条件放到where子句中,SQL
Server将会首先进行连接操作,然后使用where子句对连接后的行进行筛选。下面的两个查询展示了条件放置位子对执行结果的影响:

条件在join子句

select * 

from    t_institution i 
left outer join t_teller t

on i.inst_no = t.inst_no

and i.inst_no = “5801”

结果是:

inst_no      inst_name              inst_no      teller_no    teller_name

5801         天河区                 5801         0001         tom

5801         天河区                 5801         0002         david

5802         越秀区

5803         白云区

条件在where子句

select * 

from    t_institution i 
left outer join t_teller t

on i.inst_no = t.inst_no

where i.inst_no = “5801”

结果是:

inst_no      inst_name              inst_no      teller_no    teller_name

5801         天河区                 5801         0001         tom

5801         天河区                 5801         0002         david

2.4 自身连接

自身连接是指同一个表自己与自己进行连接。这种一元连接通常用于从自反关系(也称作递归关系)中抽取数据。例如人力资源数据库中雇员与老板的关系。

下面例子是在机构表中查找本机构和上级机构的信息。

select s.inst_no superior_inst, s.inst_name sup_inst_name, i.inst_no, i.inst_name

from t_institution i
join t_institution s

on i.superior_inst = s.inst_no

结果是:

superior_inst sup_inst_name          inst_no      inst_name

800             广州市                 5801         天河区

800             广州市                 5802         越秀区

800             广州市                 5803         白云区

2.5 交叉(无限制) 连接

交叉连接用于对两个源表进行纯关系代数的乘运算。它不使用连接条件来限制结果集合,而是将分别来自两个数据源中的行以所有可能的方式进行组合。数据集合中一的每个行都要与数据集合二中的每一个行分别组成一个新的行。例如,如果第一个数据源中有5个行,而第二个数据源中有4个行,那么在它们之间进行交叉连接就会产生20个行。人们将这种类型的结果集称为笛卡尔乘积。

大多数交叉连接都是由于错误操作而造成的;但是它们却非常适合向数据库中填充例子数据,或者预先创建一些空行以便为程序执行期间所要填充的数据保留空间。

select *

from    t_institution i 

cross join t_teller t

在交叉连接中没有on条件子句

      通过以上知识,还真是系统地学习了一番,发现inner join其实可以通过最初的多表查询方式来实现,例如:

select * from    t_institution i ,t_teller t where i.inst_no = t.inst_no and i.inst_no = "5801"

其实,inner join就是对多表查询的一种解决方案而已。而外连接,还是有其特定的用处的,实际上就相当于一个开区间,而内连接就是一个闭区间。

--1、查询课程1的成绩 比 课程2的成绩 高 的所有学生的学号.
select a.sno from
(select sno,score from sc where cno=1) a,
(select sno,score from sc where cno=2) b
where a.score>b.score and a.sno=b.sno

--2、查询平均成绩大于60分的同学的学号和平均成绩;
select sno,avg(score) as sscore from sc group by sno having avg(score) >60

--select a.sno as "学号", avg(a.score) as "平均成绩" 
--from
--(select sno,score from sc) a 
--group by sno having avg(a.score)>60

但是写成这样就会出错:语法没错

--select a.sno as "学号", avg(a.score) as "平均成绩" 
--from
--(select sno,score from sc) a 
--where avg(a.score)>60

--3、查询所有同学的学号、姓名、选课数、总成绩
select a.sno as 学号, b.sname as 姓名,
count(a.cno) as 选课数, sum(a.score) as 总成绩
from sc a, student b
where a.sno = b.sno
group by a.sno, b.sname
go

--3、查询所有同学的学号、姓名、选课数、总成绩
select student.sno as 学号, student.sname as 姓名,
 count(sc.cno) as 选课数, sum(score) as 总成绩
from student left Outer join sc on student.sno = sc.sno
group by student.sno, sname

--4、查询姓“李”的老师的个数;
select count(distinct(tname)) from teacher where tname like '李%‘

select tname as "姓名", count(distinct(tname)) as "人数" 
from teacher 
where tname like'李%'
group by tname
go

--5、查询没学过“叶平”老师课的同学的学号、姓名;
select student.sno,student.sname from student
where sno not in (select distinct(sc.sno) from sc,course,teacher
where sc.cno=course.cno and teacher.tno=course.tno and teacher.tname='叶平')

--6、查询同时学过课程1和课程2的同学的学号、姓名
select sno, sname from student
where sno in (select sno from sc where sc.cno = 1)
and sno in (select sno from sc where sc.cno = 2)
go

select c.sno, c.sname from
(select sno from sc where sc.cno = 1) a,
(select sno from sc where sc.cno = 2) b,
student c
where a.sno = b.sno and a.sno = c.sno
go

select student.sno,student.sname from student,sc where student.sno=sc.sno and sc.cno=1
and exists( Select * from sc as sc_2 where sc_2.sno=sc.sno and sc_2.cno=2)

go

--7、查询学过“叶平”老师所教所有课程的所有同学的学号、姓名
select a.sno, a.sname from student a, sc b
where a.sno = b.sno and b.cno in
(select c.cno from course c, teacher d where c.tno = d.tno and d.tname = '叶平')

go

select a.sno, a.sname from student a, sc b,
(select c.cno from course c, teacher d where c.tno = d.tno and d.tname = '叶平') e
where a.sno = b.sno and b.cno = e.cno

go

select s.sno,s.sname 
from student s,course c,teacher t,sc sc1
where sc1.sno=s.sno and sc1.cno=c.cno

and c.tno=t.tno and t.tname='叶平'

对于查询学过“叶平”老师所教所有课程的所有同学的学号、姓名的 第三种方法就是多表查询中主键和外键匹配的搜索条件

--8、查询 课程编号1的成绩 比 课程编号2的成绩 高的所有同学的学号、姓名
select a.sno, a.sname from student a,
(select sno, score from sc where cno = 1) b,
(select sno, score from sc where cno = 2) c
where b.score > c.score and b.sno = c.sno and a.sno = b.sno

--9、查询所有课程成绩小于60分的同学的学号、姓名

--select sno,sname from student
--where sno not in (select distinct sno from sc where score > 60)

select sno,sname from student
where  not exists (select distinct sno from sc where student.sno=sc.sno and score> 60)
 --NOT EXISTS = NOT IN ,意思相同不过语法上有点点区别
 --关于NOT EXISTS = NOT IN的用法在博客:http://blog.csdn.net/zhangyulin54321/article/details/7954953

--10、查询所有课程成绩大于60分的同学的学号、姓名
select sno,sname from student
where sno not in (select distinct sno from sc where score < 60)

--11、查询没有学全所有课的同学的学号、姓名
select student.sno, student.sname
from student, sc
where student.sno = sc.sno
group by student.sno, student.sname
having count(sc.cno) < (select count(cno) from course)

--12、查询至少有一门课程 与 学号为1的同学所学课程 相同的同学的学号和姓名
select distinct a.sno, a.sname
from student a, sc b
where a.sno <> 1 and a.sno=b.sno and
b.cno in (select cno from sc where sno = 1)

--13、把“sc”表中“刘老师”所教课的成绩都更改为此课程的平均成绩
update sc set score = (select avg(sc_2.score) from sc sc_2 where sc_2.cno=sc.cno)
from course,teacher where course.cno=sc.cno and course.tno=teacher.tno and teacher.tname='叶平'

--14、查询和2号同学学习的课程完全相同的其他同学学号和姓名
/* --Do first :
select sno
from sc
where sno <> 2
group by sno
having sum(cno) = (select sum(cno) from sc where sno = 2)
*/
select b.sno, b.sname
from sc a, student b
where b.sno <> 2 and a.sno = b.sno
group by b.sno, b.sname
having sum(cno) = (select sum(cno) from sc where sno = 2)

--15、删除学习“叶平”老师课的sc表记录
delete sc from course, teacher
where course.cno = sc.cno and course.tno = teacher.tno and tname = '叶平'

--16、向sc表中插入一些记录,这些记录要求符合以下条件:
--将没有课程3成绩同学的该成绩补齐, 其成绩取所有学生的课程2的平均成绩
INSERT sc select sno, 3, (select avg(score) from sc where cno = 2)
from student
where sno not in (select sno from sc where cno = 3)

--17、按平平均分从高到低显示所有学生的如下统计报表:
-- 学号,企业管理,马克思,UML,数据库,物理,课程数,平均分
SELECT sno as 学号
,max(case when cno = 1 then score end) AS 企业管理
,max(case when cno = 2 then score end) AS 马克思
,max(case when cno = 3 then score end) AS UML
,max(case when cno = 4 then score end) AS 数据库
,max(case when cno = 5 then score end) AS 物理
,count(cno) AS 课程数
,avg(score) AS 平均分
FROM sc
GROUP by sno
ORDER by avg(score) DESC

--18、查询各科成绩最高分和最低分:以如下形式显示:课程号,最高分,最低分
select cno as 课程号, max(score) as 最高分, min(score) 最低分
from sc group by cno

--19、按各科平均成绩从低到高和及格率的百分数从高到低顺序
SELECT t.cno AS 课程号,
max(course.cname)AS 课程名,
isnull(AVG(score),0) AS 平均成绩,
100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/count(1) AS 及格率
FROM sc t, course
where t.cno = course.cno
GROUP BY t.cno
ORDER BY 及格率 desc

--20、查询如下课程平均成绩和及格率的百分数(用"1行"显示): 企业管理(001),马克思(002),UML (003),数据库(004) 
select 
avg(case when cno = 1 then score end) as 平均分1,
avg(case when cno = 2 then score end) as 平均分2,
avg(case when cno = 3 then score end) as 平均分3,
avg(case when cno = 4 then score end) as 平均分4,
100 * sum(case when cno = 1 and score > 60 then 1 else 0 end) / sum(case when cno = 1 then 1 else 0 end) as 及格率1,
100 * sum(case when cno = 2 and score > 60 then 1 else 0 end) / sum(case when cno = 2 then 1 else 0 end) as 及格率2,
100 * sum(case when cno = 3 and score > 60 then 1 else 0 end) / sum(case when cno = 3 then 1 else 0 end) as 及格率3,
100 * sum(case when cno = 4 and score > 60 then 1 else 0 end) / sum(case when cno = 4 then 1 else 0 end) as 及格率4
from sc

--21、查询不同老师所教不同课程平均分, 从高到低显示
-- 张老师 数据库 88
select max(c.tname) as 教师, max(b.cname) 课程, avg(a.score) 平均分
from sc a, course b, teacher c
where a.cno = b.cno and b.tno = c.tno
group by a.cno
order by 平均分 desc

--22、查询如下课程成绩均在第3名到第6名之间的学生的成绩:
-- [学生ID],[学生姓名],企业管理,马克思,UML,数据库,平均成绩
select top 6 max(a.sno) 学号, max(b.sname) 姓名,
max(case when cno = 1 then score end) as 企业管理,
max(case when cno = 2 then score end) as 马克思,
max(case when cno = 3 then score end) as UML,
max(case when cno = 4 then score end) as 数据库,
avg(score) as 平均分
from sc a, student b
where a.sno not in (select top 2 sno from sc where cno = 1 order by score desc)
  and a.sno not in (select top 2 sno from sc where cno = 2 order by score desc)
  and a.sno not in (select top 2 sno from sc where cno = 3 order by score desc)
  and a.sno not in (select top 2 sno from sc where cno = 4 order by score desc)
  and a.sno = b.sno
group by a.sno

--23、统计打印各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60]
select sc.cno as 课程ID, cname as 课程名称,
sum(case when score >= 85 then 1 else 0 end) as [100-85],
sum(case when score < 85 and score >= 70 then 1 else 0 end) as [85-70],
sum(case when score < 70 and score >= 60 then 1 else 0 end) as [70-60],
sum(case when score < 60 then 1 else 0 end) as [ <60]
from sc, course
where sc.cno = course.cno
group by sc.cno, cname

--24、查询学生平均分及其名次
--drop table t1
--select sno, avg(score) as pjf into t1 from sc group by sno
--go
--
--drop table t2
--select distinct avg(score) as pjf into t2 from sc group by sno
--go
--
--select
--    (select count(1) from t2 where pjf >= t1.pjf) as 名次,
--    sno as 学号,
--    pjf as 平均分
--from t1
--order by pjf desc
--go
select
    (select count(1)
    from (select distinct avg(score) as pjf from sc group by sno) as t2
    where pjf >= t1.pjf) as 名次,
    sno as 学号,
    pjf as 平均分
from (select sno, avg(score) as pjf from sc group by sno) as t1
order by pjf desc
go

--25、查询各科成绩前三名的记录:(不考虑成绩并列情况) 
--drop table aa
--select sno, cno, score into aa from sc order by cno, score desc
--
--drop table bb
--select distinct cno, score into bb from sc order by cno, score desc
--
--select aa.* from aa
--where aa.score in (select top 3 score from bb where aa.cno = bb.cno)

select * 
from (select top 9999 sno, cno, score from sc order by cno, score desc) as aa
where aa.score in 
    (select top 3 score
    from (select distinct top 9999 cno, score from sc order by cno, score desc) as bb
    where aa.cno = bb.cno)

--26、查询每门课程被选修的学生数 
 select cno,count(sno) from sc group by cno

--27、查询出只选修了一门课程的全部学生的学号和姓名 
SELECT sc.sno, student.sname, count(cno) AS 选课数 
FROM sc, student 
WHERE sc.sno = student.sno
GROUP BY sc.sno, student.sname
HAVING count(cno) = 3

--28、查询男生、女生人数 
select 
(select count(1) from student where ssex = '男') 男生人数,
(select count(1) from student where ssex = '女') 女生人数

--29、查询姓“张”的学生名单 
 SELECT sname FROM student WHERE sname like '张%'

--30、查询同名同性学生名单,并统计同名人数
--select sname, count(1) from student group by sname having count(1) > 1

--31、1981年出生的学生名单(注:student表中sage列的类型是datetime) 
select sname, CONVERT(char(4), DATEPART(year,sage)) as age 
from student 
where DATEPART(year,sage)=1981

--32、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列 
select cno 课程号, avg(score) 平均分
from sc group by cno order by 平均分 asc, cno desc

--33、查询平均成绩大于80的所有学生的学号、姓名和平均成绩
select sno, avg(score)
from sc
group by sno
having avg(score) > 80

--34、查询 数据库 分数 低于60的学生姓名和分数
select c.sname, a.score
from sc a, course b, student c
where a.cno = b.cno and a.sno = c.sno
 and b.cname = '数据库' and score < 60

--35、查询所有学生的选课情况
SELECT sc.sno 学号,sname 姓名,cname 课程, sc.cno 课号
FROM sc,student,course 
WHERE sc.sno=student.sno and sc.cno=course.cno
ORDER BY sc.sno

--36、查询成绩在70分以上的学生姓名、课程名称和分数
SELECT student.sno,student.sname,sc.cno,sc.score 
FROM student,Sc 
WHERE sc.score>=70 AND sc.sno=student.sno; 

--37、查询不及格的课程,并按课程号从大到小排列
 select cno, score from sc where score < 60 order by cno

--38、查询课程编号为3且课程成绩在80分以上的学生的学号和姓名
select sc.sno,student.sname from sc,student where sc.sno=student.sno and score>80 and cno=3

--39、求选了课程的学生人数 
select count(distinct sno) from sc

--40、查询选修“叶平”老师所授课程的学生中,成绩最高的学生姓名及其成绩 
select student.sname,cname, score 
from student,sc,course C,teacher 
where student.sno=sc.sno and sc.cno=C.cno and C.tno=teacher.tno
and teacher.tname ='叶平'
and sc.score=(select max(score)from sc where cno = C.cno)

--41、查询各个课程及相应的选修人数 
select cno 课程号, count(1) 选修人数 from sc group by cno

--42、查询不同课程成绩相同的学生的学号、课程号、学生成绩 
select distinct A.sno, A.cno,B.score
from sc A ,sc B
where A.Score=B.Score and A.cno <>B.cno
order by B.score

--43、查询每门课程成绩最好的前两名的学生ID
--先按照 课程, 成绩 高低 对 sc表 排序
--select * from sc order by cno, score desc
select * from sc a
where score in (select top 2 score from sc where a.cno = sc.cno order by sc.score desc)
order by a.cno, a.score desc

--查询各单科状元
select * from sc a
where score = (select top 1 score from sc where a.cno = sc.cno order by sc.score desc)
order by a.cno, a.score desc

--44、统计每门课程的学生选修人数(至少有2人选修的课程才统计)。要求输出课程号和选修人数,
--查询结果按人数降序排列,若人数相同,按课程号升序排列 
select cno as 课程号,count(1) as 人数 
from sc 
group by cno having count(1) > 1
order by count(1) desc,cno 

--45、检索至少选修了5门课程的学生学号
select sno from sc group by sno having count(1) >= 5

--46、查询全部学生都选修的课程的课程号和课程名
--(思路:查询最受欢迎的课程是啥)
--select cno 课程ID, count(1) 选修人数 from sc group by cno
select course.cno, cname
from sc, course
where sc.cno = course.cno
group by course.cno, cname
having count(sc.cno) = (select count(1) from student)

--查询最受欢迎的课程
select cno 课程ID, count(cno) 选修人数
from sc group by cno
having count(cno) in (select top 1 count(cno) from sc group by cno order by count(cno) desc)
order by 选修人数 desc

--47、查询没学过“叶平”老师讲授的任一门课程的学生姓名
--思路: 先得到学过“叶平”老师讲授的所有课程清单
--select a.cno from course a, teacher b where a.tno = b.tno and b.tname = '叶平')
--然后: 从 sc表中 得到 学过上述课程的 所有学生清单
--select sno from sc where cno in
--(select a.cno from course a, teacher b where a.tno = b.tno and b.tname = '叶平'))
--最后: 从student表中 得到不在上数学生清单中的其他学生,即为最后的查询结果
select sno, sname from student
where sno not in(
    select sno from sc where cno in
    (select a.cno from course a, teacher b where a.tno = b.tno and b.tname = '叶平'))

select sno, sname from student
where sno not in
    (select sno from course,teacher,sc
    where course.tno=teacher.tno and sc.cno=course.cno and tname='叶平')

--48、查询两门以上不及格课程的同学的学号及其平均成绩
--思路: 先查询出所有不及格的sc中的记录
--select sno, score from sc where score < 60
select sno 学号, avg(score) 平均分, count(1) 不及格课程数
from sc where score < 60 group by sno having count(1) > 2

--49、检索4号课程分数大于60的同学学号,按分数降序排列
select sno, score from sc where cno = 4 and score > 60 order by score desc

--50、删除2号同学的课程1的成绩
--delete sc where sno = 2 and cno = 1
--select * from sc where sno = 2 and cno = 1
delete from sc where sno = 2 and cno = 1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: