数据库编程基本练习题
1、用一条SQL语句查询出每门课都大于80分的学生姓名
准备数据的sql代码:
create table score( id int primary key auto_increment, name varchar(20), subject varchar(20), score int); insert into score values (null,'张三','语文',81), (null,'张三','数学',75), (null,'李四','语文',76), (null,'李四','数学',90), (null,'王五','语文',81), (null,'王五','数学',100), (null,'王五 ','英语',90);
答案:
select distinct name from score where name not in (select distinct name from score where score<=80)
2、每个月份的发生额都比101科目多的科目
请用SQL语句实现:从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。请注意:TestDB中有很多科目,都有1-12月份的发生额。 AccID:科目代码,Occmonth:发生额月份,DebitOccur:发生额。 数据库名:JcyAudit,数据集:Select * from TestDB
准备数据的sql代码: drop table if exists TestDB; create table TestDB( id int primary key auto_increment, AccID varchar(20), Occmonth date, DebitOccur bigint); insert into TestDB values (null,'101','1988-1-1',100), (null,'101','1988-2-1',110), (null,'101','1988-3-1',120), (null,'101','1988-4-1',100), (null,'101','1988-5-1',100), (null,'101','1988-6-1',100), (null,'101','1988-7-1',100), (null,'101','1988-8-1',100); --复制上面的数据,故意把第一个月份的发生额数字改小一点 insert into TestDB values (null,'102','1988-1-1',90), (null,'102','1988-2-1',110), (null,'102','1988-3-1',120), (null,'102','1988-4-1',100), (null,'102','1988-5-1',100), (null,'102','1988-6-1',100), (null,'102','1988-7-1',100), (null,'102','1988-8-1',100); --复制最上面的数据,故意把所有发生额数字改大一点 insert into TestDB values (null,'103','1988-1-1',150), (null,'103','1988-2-1',160), (null,'103','1988-3-1',180), (null,'103','1988-4-1',120), (null,'103','1988-5-1',120), (null,'103','1988-6-1',120), (null,'103','1988-7-1',120), (null,'103','1988-8-1',120); --复制最上面的数据,故意把所有发生额数字改大一点 insert into TestDB values (null,'104','1988-1-1',130), (null,'104','1988-2-1',130), (null,'104','1988-3-1',140), (null,'104','1988-4-1',150), (null,'104','1988-5-1',160), (null,'104','1988-6-1',170), (null,'104','1988-7-1',180), (null,'104','1988-8-1',140); --复制最上面的数据,故意把第二个月份的发生额数字改小一点 insert into TestDB values (null,'105','1988-1-1',100), (null,'105','1988-2-1',80), (null,'105','1988-3-1',120), (null,'105','1988-4-1',100), (null,'105','1988-5-1',100), (null,'105','1988-6-1',100), (null,'105','1988-7-1',100), (null,'105','1988-8-1',100);
答案:
select distinct AccID from TestDB where AccID not in (select TestDB.AccIDfrom TestDB, (select * from TestDB where AccID='101') as db101 where TestDB.Occmonth=db101.Occmonth and TestDB.DebitOccur<=db101.DebitOccur );
3、统计每年每月的信息
year month amount 1991 1 1.1 1991 2 1.2 1991 3 1.3 1991 4 1.4 1992 1 2.1 1992 2 2.2 1992 3 2.3 1992 4 2.4 查成这样一个结果: year m1 m2 m3 m4 1991 1.1 1.2 1.3 1.4 1992 2.1 2.2 2.3 2.4
准备sql语句: drop table if exists sales; create table sales( id int auto_increment primary key, year varchar(10), month varchar(10), amount float(2,1)); insert into sales values (null,'1991','1',1.1), (null,'1991','2',1.2), (null,'1991','3',1.3), (null,'1991','4',1.4), (null,'1992','1',2.1), (null,'1992','2',2.2), (null,'1992','3',2.3), (null,'1992','4',2.4);
答案:
select sales.year, (select t.amount from sales as t where t.month='1' and t.year = sales.year) as 'm1', (select t.amount from sales as t where t.month='2' and t.year = sales.year) as 'm2', (select t.amount from sales as t where t.month='3' and t.year = sales.year) as 'm3', (select t.amount from sales as t where t.month='4' and t.year = sales.year) as 'm4' from sales group by year
4、显示文章标题,发帖人、最后回复时间
表:id,title,postuser,postdate,parentid
准备sql语句: drop table if exists articles; create table articles( id int auto_increment primary key, title varchar(50), postuser varchar(10), postdate datetime, parentid int references articles(id) ); insert into articles values (null,'第一条','张三','1998-10-10 12:32:32',null), (null,'第二条','张三','1998-10-10 12:34:32',null), (null,'第一条回复1','李四','1998-10-10 12:35:32',1), (null,'第二条回复1','李四','1998-10-10 12:36:32',2), (null,'第一条回复2','王五','1998-10-10 12:37:32',1), (null,'第一条回复3','李四','1998-10-10 12:38:32',1), (null,'第二条回复2','李四','1998-10-10 12:39:32',2), (null,'第一条回复4','王五','1998-10-10 12:39:40',1);
答案:
select zhu.title,zhu.postuser, (select max(fu.postdate) from articles as fu where zhu.id = fu.parentid) as postdata from articles as zhu where zhu.parentid is null
5、删除除了id号不同,其他都相同的学生冗余信息
学生表 如下: id号 学号 姓名 课程编号 课程名称 分数 1 2005001 张三 0001 数学 69 2 2005002 李四 0001 数学 89 3 2005001 张三 0001 数学 69
准备数据: create table student2( id int auto_increment primary key, code varchar(20), name varchar(20) ); insert into student2 values (null,'2005001','张三'), (null,'2005002','李四'), (null,'2005001','张三');
答案:
delete from student2 where id not in(select min(id) from (select * from student2) as t group by t.name);
6、航空网的几个航班查询题:
实验环境: create table city( cityID int auto_increment primary key, cityName varchar(20)); create table flight ( flightID int auto_increment primary key, StartCityID int references city(cityID), endCityID int references city(cityID), StartTime timestamp); //航班本来应该没有日期部分才好,但是下面的题目当中涉及到了日期 insert into city values (null,'北京'), (null,'上海'), (null,'广州'); insert into flight values (null,1,2,'9:37:23'), (null,1,3,'9:37:23'), (null,1,2,'10:37:23'), (null,2,3,'10:37:23');
(1) 查询起飞城市是北京的所有航班,按到达城市的名字排序
答案:
select * from flight as f,city as c where f.endCityID = c.cityID and StartCityID = (select cityID from city where cityName = "北京") order by endCityID desc
(2)查询北京到上海的所有航班纪录(起飞城市,到达城市,起飞时间,航班号)
答案:
select c1.cityName as '起飞城市',c2.cityName as '到大城市',f.StartTime as '到大城市',f.flightID as '航班号' from city as c1,city as c2,flight f where c1.cityID = f.StartCityID and c2.cityID = f.endCityID and c1.cityName = "北京" and c2.cityName = "上海"
(3)查询具体某一天(2005-5-8)的北京到上海的的航班次数
答案:
select count(*) from city as c1,city as c2,flight as f where c1.cityID = f.StartCityID and c2.cityID = f.endCityID and c1.cityName = "北京" and c2.cityName = "上海" and 查帮助获得的某个日期处理函数(startTime) like '2005-5-8%'
7、查出比经理薪水还高的员工信息:
准备数据: Drop table if not exists employees; create table employees( id int primary key auto_increment, name varchar(50), salary int, managerid int references employees(id)); insert into employees values (null,' lhm',10000,null), (null,' zxx',15000,1), (null,'flx',9000,1), (null,'tg',10000,2), (null,'wzg',10000,3); Wzg大于flx,lhm大于zxx
答案:
select e.* from employees as m,employees as e where m.id = e.managerid and m.salary < e.salary
8、求出小于45岁的各个老师所带的大于12岁的学生人数
实验数据: drop table if exists tea_stu; drop table if exists teacher; drop table if exists student; create table teacher( teaID int primary key, name varchar(50), age int); create table student( stuID int primary key, name varchar(50), age int); create table tea_stu( teaID int references teacher(teaID), stuID int references student(stuID)); insert into teacher values (1,'zxx',45), (2,'lhm',25) , (3,'wzg',26) , (4,'tg',27); insert into student values (1,'wy',11), (2,'dh',25) , (3,'ysq',26) , (4,'mxc',27); insert into tea_stu values (1,1), (1,2), (1,3); insert into tea_stu values (2,2), (2,3), (2,4); insert into tea_stu values (3,3), (3,4), (3,1); insert into tea_stu values (4,4), (4,1), (4,2), (4,3);
答案:
select teacher.name,count(student.name) as count from teacher,student,tea_stu where teacher.teaID = tea_stu.teaID and student.stuID = tea_stu.stuID and teacher.age < 45 and student.age > 12 group by teacher.name
9、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决?
alter table drop column score; alter table add colunm score int;
可能会很快,但是需要试验,试验不能拿真实的环境来操刀,并且要注意,
这样的操作时无法回滚的,在我的印象中,只有inert update delete等DML语句才能回滚,
对于create table,drop table ,alter table等DDL语句是不能回滚。
解决方案一, update user set score=0; 解决方案二,假设上面的代码要执行好长时间,超出我们的容忍范围,那我就
alter table user drop column score;alter table user add column score int。
下面代码实现每年的那个凌晨时刻进行清零
Runnable runnable = new Runnable(){ public void run(){ clearDb(); schedule(this,new Date(new Date().getYear()+1,0,0)); } }; schedule(runnable,new Date(new Date().getYear()+1,0,1));
10、用一条SQL 语句 查询出每门课都大于80 分的学生姓名
name course grade 张三 语文 81 张三 数学 75 李四 语文 76 李四 数学 90 王五 语文 81 王五 数学 100 王五 英语 90
答案:
select name from table group by name having min(grade) > 80
11. 现有学生表如下:
自动编号 学号 姓名 课程编号 课程名称 分数 1 2005001 张三 0001 数学 69 2 2005002 李四 0001 数学 89 3 2005001 张三 0001 数学 69
删除除了自动编号不同, 其他都相同的学生冗余信息
答案:
select 自动编号 from 表 where 自动编号 not in (select min(自动编号) from 表 group by 学号,姓名,课程编号,课程名称,分数)
12、一个叫 team 的表,里面只有一个字段name, 一共有4 条纪录,分别是a,b,c,d, 对应四个球对,现在四个球对进行比赛,用一条sql 语句显示所有可能的比赛组合
select a.name as '主队',b.name as '客队' from team as a,team as b where a.name < b.name
13、查询” 01 “课程比” 02 “课程成绩高的学生的信息及课程分数
实验数据:
学生表: create table Student( Sid varchar(6), Sname varchar(10), Sage datetime, Ssex varchar(10)); insert into Student values('01' , '赵雷' , '1990-01-01' , '男'); insert into Student values('02' , '钱电' , '1990-12-21' , '男'); insert into Student values('03' , '孙风' , '1990-05-20' , '男'); insert into Student values('04' , '李云' , '1990-08-06' , '男'); insert into Student values('05' , '周梅' , '1991-12-01' , '女'); insert into Student values('06' , '吴兰' , '1992-03-01' , '女'); insert into Student values('07' , '郑竹' , '1989-07-01' , '女'); insert into Student values('08' , '王菊' , '1990-01-20' , '女')
成绩表 create table SC( Sid varchar(10), Cid varchar(10), score decimal(18,1)); insert into SC values('01' , '01' , 80); insert into SC values('01' , '02' , 90); insert into SC values('01' , '03' , 99); insert into SC values('02' , '01' , 70); insert into SC values('02' , '02' , 60); insert into SC values('02' , '03' , 80); insert into SC values('03' , '01' , 80); insert into SC values('03' , '02' , 80); insert into SC values('03' , '03' , 80); insert into SC values('04' , '01' , 50); insert into SC values('04' , '02' , 30); insert into SC values('04' , '03' , 20); insert into SC values('05' , '01' , 76); insert into SC values('05' , '02' , 87); insert into SC values('06' , '01' , 31); insert into SC values('06' , '03' , 34); insert into SC values('07' , '02' , 89); insert into SC values('07' , '03' , 98)
课程表 create table Course( Cid varchar(10), Cname varchar(10), Tid varchar(10)); insert into Course values ('01' , '语文' , '02'); insert into Course values ('02' , '数学' , '01'); insert into Course values ('03' , '英语' , '03')
教师表 create table Teacher( Tid varchar(10), Tname varchar(10)); insert into Teacher values ('01' , '张三'); insert into Teacher values ('02' , '李四'); insert into Teacher values ('03' , '王五')
14、 根据(13题)表查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
答案:
select s.Sid,s.Sname,avg(score) as a from Student as s,SC where s.Sid = SC.Sid group by s.Sid having a>60
15、根据(13题)表查询在 SC 表存在成绩的学生信息
答案:
select s.* from Student as s,SC where s.Sid = SC.Sid group by Sid
16、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
答案:
select s.Sid,s.Sname,count(SC.Cid),sum(score) from Student as s left join SC on s.Sid = SC.Sid group by s.Sid
17、查有成绩的学生信息
答案:
select s.Sid,S.Sname,count(score),sum(score), sum(case when SC.Cid=01 then score else null end) as score_1, sum(case when SC.Cid=02 then score else null end) as score_2, sum(case when SC.Cid=03 then score else null end) as score_3 from Student as s,SC,Course where s.Sid = SC.Sid and SC.Cid = Course.Cid group by s.Sid
18、查询「李」姓老师的数量
答案:
select count(*) from Teacher where Tname like '李%'
19、查询学过「张三」老师授课的同学的信息
select s.* from Student as s,SC,course,Teacher where s.Sid=SC.Sid and Course.Cid=SC.Cid and Teacher.Tid=Course.Tid and Teacher.Tname = '张三' group by s.Sid
20、查询没有学全所有课程的同学的信息
select * from Student where Sid in (select Sid from SC group by Sid having count(cid) < 3)
21、查询至少有一门课与学号为” 01 “的同学所学相同的同学的信息
select s.* from SC,Student as s where Cid in (select Cid from SC where Sid = '01') and s.Sid = SC.Sid group by Sid
22、查询没学过”张三”老师讲授的任一门课程的学生姓名
select Sname from Student where Sname not in (select s.Sname from Teacher as t,SC,Course,Student as s where t.Tid = Course.Tid and s.Sid=SC.Sid and SC.Cid=Course.Cid and t.Tname = '张三')
23、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select s.Sid,s.Sname,avg(score) from Student as s,SC where s.Sid = SC.Sid and SC.score < 60 group by s.Sid having count(score > 2)
24、检索” 01 “课程分数小于 60,按分数降序排列的学生信息
select s.*,SC.score from Student as s,SC where Cid = '01' and s.Sid=SC.Sid and score < 60 group by score desc
25、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
select Sid, sum(case when Cid=01 then score else null end) as score_01, sum(case when Cid=02 then score else null end) as score_02, sum(case when Cid=03 then score else null end) as score_03, avg(score) from SC group by Sid order by avg(score) desc
26、查询各科成绩最高分、最低分和平均分,以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率(及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90)。 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
select c.cid as 课程号, c.cname as 课程名称, count(*) as 选修人数, max(score) as 最高分, min(score) as 最低分, avg(score) as 平均分, sum(case when score >= 60 then 1 else 0 end)/count(*) as 及格率, sum(case when score >= 70 and score < 80 then 1 else 0 end)/count(*) as 中等率, sum(case when score >= 80 and score < 90 then 1 else 0 end)/count(*) as 优良率, sum(case when score >= 90 then 1 else 0 end)/count(*) as 优秀率 from sc, course c where c.cid = sc.cid group by c.cid order by count(*) desc, c.cid asc
27、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
select c.Cid as 课程编号, c.Cname as 课程名称, A.* from course as c, (select Cid, sum(case when score >= 85 then 1 else 0 end)/count(*) as 100_85, sum(case when score >= 70 and score < 85 then 1 else 0 end)/count(*) as 85_70, sum(case when score >= 60 and score < 70 then 1 else 0 end)/count(*) as 70_60, sum(case when score < 60 then 1 else 0 end)/count(*) as 60_0 from SC group by Cid) as A where c.Cid = A.Cid
28、查询出只选修两门课程的学生学号和姓名
select s.Sid,s.Sname,count(sc.Cid) from Student as s,SC as sc where s.Sid = sc.Sid group by s.Sid having count(sc.Cid) = 2
29、查询名字中含有「风」字的学生信息
select Sname from Student where Sname like '%风%'
30、查询 1990 年出生的学生名单
select * from Student where Sage like('1990%')
31、成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
select s.* from Student as s,Teacher as t,SC as sc,Course as c where s.Sid=sc.Sid and c.Tid=t.Tid and sc.Cid = c.Cid and t.Tname='张三' order by sc.score desc limit 0,1
32、成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
select s.* from Student as s,SC where SC.Sid=s.Sid and SC.Cid = (select c.Cid from Teacher as t,Course as c where t.Tid = c.Tid and t.Tname = '张三') and SC.score = ( select sc.score from Student as s,Teacher as t,SC as sc,Course as c where s.Sid=sc.Sid and c.Tid=t.Tid and sc.Cid = c.Cid and t.Tname='张三' order by sc.score desc limit 0,1 )
33、查询各学生的年龄,只按年份来算
select Sname,year(now())-year(Sage) as age from Student
34、按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
select Sname,year(now())-year(Sage)-1 as age from Student
35、查询本周过生日的学生
select Sname from Student where week(now()) = week(Sage)
36、查询下周过生日的学生
select Sname from Student where (week(now())+1) = week(Sage)
37、查询本月过生日的学生
select Sname from Student where month(now()) = month(Sage)
38、查询下月过生日的学生
select Sname from Student where (month(now())+1) = month(Sage)
39、查询和” 01 “号的同学学习的课程完全相同的其他同学的信息
select * from Student where sid in (select sid from SC where cid in (select sc.Cid from SC where sc.Sid='01') and sid <>'01' group by sid having count(cid) >= 3 )