实验四 复杂查询

实验四 复杂查询

教材使用的是雷景生版本的《数据库原理及应用(第2版)》

一、 实验目的:
掌握两个表以上的连接查询的应用,包括嵌套查询。

二、 实验内容:
初始表格三张:
Student表、Course表和SC表
Student
Course
SC

1、 同一数据库中的多表查询
(1) 查询比“林红”年纪大的男学生的信息。

select *
from Student 
where Sex ='男'
and Birth < any
(select Birth 
from Student
where Sname='林红')
//这里的思路是先提取(或者叫做查询)林红的生日再使用比较运算符

结果:
在这里插入图片描述
为空,因为没有比林红年龄大的男同学
·
·
·
(2) 查询所有学生的选课信息,包括学号、姓名、课号、课程名、成绩。

select Student.Sno,Sname,Course.Cno,Cname,Grade
from Student,Course,SC  
where Student.Sno=SC.Sno and Course.Cno=SC.Cno

结果:
在这里插入图片描述
这里要注意的是,如果代码的where后没有用自然连接的话会出现如下的数据冗杂情况(会变成三张表的笛卡尔乘积)
在这里插入图片描述
·
·
·
(3) 查询已选课学生的学号、姓名、课程名、成绩。

select SC.Sno,Student.Sname,Cname,Grade
from SC left outer join Student on(student.sno=sc.sno),Course 
where Course.Cno=SC.Cno 

结果:
在这里插入图片描述
·
·
·
(4) 查询选修了“C语言程序设计”的学生的学号和姓名。

select Student.Sno,Sname
from Student,SC 
where Student.Sno=SC.Sno and SC.Cno in 
(select Cno
from Course
where Cname='C语言程序设计')

结果:
在这里插入图片描述
·
·
·
(5) 查询与“张虹”在同一个班级的学生的学号、姓名、家庭住址。

select Sno,Sname,Home_addr 
from Student 
where Classno in
(select Classno 
from Student 
where Sname='张虹')

结果:
在这里插入图片描述
·
·
·
(6) 查询其他班级中比“051”班所有学生年龄大的学生的学号、姓名。

select Sno,Sname  
from Student 
where Classno <>'051'
and Birth<all(select Birth  
              from Student 
              where Classno='051') 

结果:
在这里插入图片描述
·
·
·
(7) (选做)查询选修了全部课程的学生的姓名。
方法一:

select Sname
from Student
where Sno in
(select Sno from SC
group by Sno
having count(*) = (select count(*) from Course ))

结果:
在这里插入图片描述
方法二:

select Sname 
from Student
where not exists 
(select *
from Course
where not exists
          (select *
		   from SC
		   where Student.Sno=SC.Sno
		   and Course.Cno=SC.Cno))             

结果:
在这里插入图片描述
·
·
·
(8) (选做)查询至少选修了学生“20110002”选修的全部课程的学生的学号、姓名。
方法一:

select Student.Sno,Sname
from Student,SC
where Student.Sno=SC.Sno 
and Cno =
(select Cno from SC
where Sno='20110002')   

结果:
在这里插入图片描述
方法二:

select distinct sx.Sno,Sname
from SC sx left outer join Student on(sx.Sno =Student.Sno )
where not exists
(select * 
from SC sy
where sy.Sno ='20110002'and
not exists
(select * from SC sz
where sz.Cno=sy.Cno
and sz.Sno=sx.Sno) )   

结果:
在这里插入图片描述
·
·
·
(9) 查询学生的学号、姓名、学习课程名及课程成绩。

select Student.Sno,Sname,Cname,Grade
from Student,Course,SC 
where Student.Sno=SC.Sno and Course.Cno=SC.Cno

结果:
在这里插入图片描述
·
·
·
(10) 查询选修了“高数”课且成绩至少高于选修课程号为“002”课程的学生的学号、课程号、成绩,并按成绩从高到低排列。

select Sno,Cno,Grade
from SC
where Cno in(select Cno from Course 
             where Cname='高数' )
and Grade >all(select Grade from SC 
               where Cno='002')
order by Grade desc

结果:
在这里插入图片描述
·
·
·
(11) 查询选修3门以上课程的学生的学号、总成绩(不统计不及格的课程),并要求按总成绩的降序排列出来。

select Sno,sum(case when Grade>=60 then grade else 0 end)as'allg'
from SC 
where Sno in
(select Sno from SC group by Sno having count(*)>3)
group by Sno 
order by allg desc 

结果:
在这里插入图片描述
·
·
·
(12) 查询多于3名学生选修的并以3结尾的课程号的平均成绩。

select Cno,AVG(Grade)as 'pingjun' 
from SC
where Cno in
(select Cno from SC group by Cno having COUNT(*)>3)      
and Cno='%3'
group by Cno                                               

结果:
在这里插入图片描述

·
·
·
(13) 查询最高分与最低分之差大于5分的学生的学号、姓名、最高分、最低分。

select SC.Sno,Sname,MAX(Grade),MIN(Grade)
from SC,Student
where SC.Sno in
(select Sno 
from SC 
group by Sno
having COUNT(*)>2 
and MAX(Grade)-MIN(Grade)>5)   
and SC.Sno=Student.Sno    
group by SC.Sno,Sname             

结果:
在这里插入图片描述

·
·
·
(14) 创建表Studen_other,结构同Student,输人若干记录,部分记录和Student表中的相同。
创建Student_other表如下:
在这里插入图片描述
①查询同时出现在Student表和Student_other表中的记录。

select * from Student
intersect
select * from Student_other

结果:
在这里插入图片描述

②查询Student表和Student_other表中的全部记录。

select * from Student
select * from Student_other

结果:在这里插入图片描述
2、多个数据库间的多表查询
(选做)创建一个数据库Student_info_other,参数自定。
(1)当前数据库为Student_info,将Student_info数据库中的表Student_other复制到Student_info_other 中。
(2)查询同时出现在Student表和Student_info__other 数据库Student_other表中的记录。

3、外连接查询
(1)查询所有课程信息及其选课信息,包含未被学生选修的课程。

select * 
from Course left outer join SC on(Course.Cno=SC.Cno )

结果:
在这里插入图片描述
(2)查询所有学生信息,所有课程信息及其选课信息,包含未选修课程的学生及未被学生选修的课程。

select  * 
from Student 
left join SC on (Student.Sno=SC.Sno)
left join Course on(SC.Cno=Course.Cno)

结果:
在这里插入图片描述

### SQL 实验复杂查询解决方案 在处理复杂SQL 查询时,通常需要综合运用种技术手段来提高效率并减少资源消耗。以下是针对复杂查询的一些常见示例及其解决方案。 #### 示例一:通过索引来优化查询性能 对于涉及量数据的,在 `WHERE` 和 `ORDER BY` 子句中的字段上创建合适的索引可以显著提升查询速度[^3]。例如: 假设有一个名为 `employees` 的,其中包含员工的信息以及他们的部门编号 (`department_id`) 和入职日期 (`hire_date`)。如果经常执行如下查询: ```sql SELECT * FROM employees WHERE department_id = 5 ORDER BY hire_date DESC; ``` 可以通过为 `department_id` 和 `hire_date` 创建复合索引来加速此操作: ```sql CREATE INDEX idx_emp_dept_hire ON employees(department_id, hire_date); ``` 这样可以在过滤条件和排序过程中利用索引结构,从而避免全扫描。 #### 示例二:分组统计与聚合函数的应用 当需要计算某个特定时间段内的销售总额或者平均订单金额时,可以使用 GROUP BY 结合 SUM() 或 AVG() 函数完成这些任务。比如有张记录商品交易详情的数据叫做 orders (order_id, product_name, quantity, price),那么求每种产品的总销量可写成下面形式: ```sql SELECT product_name, SUM(quantity*price) AS total_sales FROM orders GROUP BY product_name; ``` 这里我们不仅实现了按产品名称汇总销售额的功能,还展示了如何正确地组合个列来进行数值运算后再做进一步分析[^1]。 #### 示例三:子查询与连接操作相结合解决问题 有时候单靠简单的 SELECT 不足以满足业务需求,则可能需要用到更高级别的语法——嵌套查询或者是 JOIN 。举个例子来说吧 ,如果我们想知道哪些客户在过去一个月里至少购买过一次我们的旗舰型号手机,并且他们所在城市的人口数于一百万的话,就可以按照这种方式构建语句: ```sql SELECT c.customer_id, c.name FROM customers c INNER JOIN ( SELECT DISTINCT customer_id FROM purchases p WHERE purchase_date >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH) AND item='flagship_phone' ) recent_purchases rp ON c.customer_id=rp.customer_id INNER JOIN cities ci ON c.city_id=ci.id WHERE ci.population > 1000000; ``` 上述代码片段首先筛选出了符合条件的商品最近购入者列作为内部临时结果集;接着再把这个集合跟顾客基本信息进行匹配找到对应的名字等属性;最后再次关联城市资料确认居住环境规模是否达标[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值