数据库编程基本练习题

 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 自动编号 fromwhere 自动编号 not in 
(select min(自动编号) fromgroup 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
)

 

posted @ 2019-06-27 19:57  追风的小蚂蚁  阅读(3077)  评论(0编辑  收藏  举报