2020.9.12课堂练习(mysql课堂练习答案)

14.相关表结构:
学生表 tb_student(编号 stuid、姓名 stuname、年龄stuage、性别 stusex)
课程表 tb_course(课程编号 courseId、课程名称 coursename、教师编号 teaid)
成绩表 tb_score(学生编号 stuid、课程编号 courseid、成绩 score)
教师表 tb_Teacher(教师编号 teaid、姓名 teaname)

(1)查询没有学全所有课的同学的学号、姓名:
select c.stuid,stuname from tb_score c join tb_student s on c.stuid=c.stuid group by a.stu_id having count(distinct courseid) <> (select count(courseid) from tb_course);

(2) 查询课程编号为“001的课程比课程编号为“002课程成绩高的所有学生的学号:
select a.stu_id,a.score score1,b.score score2 from tb_score a join tb_score b on a.stuid=b.stuid where a.score>b.score and a.corseid='001' and b.corseid='002';
(3)查询各科成绩最高和最低的分:以如下形式显示:课程名称,最高分,最低分
select corsename,max(score),min(score) from tb_course c join tb_score s on c.courseid=s.courseid group by s.courseid;
15. 根据以下两张数据表回答问题:
数据表A

编码(key) 数据日期(ds)
k1 2009-07-07
K2 2009-07-08
K3 2009-07-07
K5 2009-07-07

数据表B

编码(key) 数据日期(ds)
k1 2009-07-07
K2 2009-07-07
K3 2009-07-08
K4 2009-07-07

以下两个查询语句的结果分别是什么?
SELECT a. key, a. ds, b. key, b. ds FROM a LEFT OUTER JOIN b ON(a. key=b. key) WHERE a. ds=' 2009-07-07' AND b. ds='2009-07-07';

a.key a.ds b.key b.ds
k1 2009-07-07 k1 2009-07-07

SELECT a. key, a. ds, b. key, b. ds FROM a LEFT OUTER JOIN b ON(a. key=b. key AND a. dse=' 2009-07-07', AND b. ds='2009-07-07');

a.key a.ds b.key b.ds
k1 2009-07-07 k1 2009-07-07
k2 2009-07-08 null null
k3 2009-07-07 null null
k5 2009-07-07 null null

16.产品入库表(ProductList)不同产品的入库时间可能相同。

入库序号(ID) 产品名称(ProductName) 数量(Count) 入库时间 (DataTime)
0001 诺基亚N95 20 2009-1-1 00:00:00
0002 诺基亚N75 30 2009-1-1 00:00:00
0003 诺基亚N95 50 2009-1-1 00:10:00

用一条语句查询所有产品的最后一次入库记录。
select * from productlist order by datatime limit 1; select * from (select * from productlist order by datatime) a group by a.productname;
17. 使用SQL解决以下问题。
部门表dept:
dept-no 部门编号
dept-name 部门名称
location 部门位置
员工表emp:
emp_no 编号
emp_name 姓名
title 职位
mar 领导编号
hire-date 雇佣日期
month-time 发工资日期
salary 基本工资
bonus 奖金
dept-no 所在部门编号
工资等级表grade:
grade 工资等级
losal 此等级工资下限
hisal 此等级工资上限
(1)写一条查询语句,返回:部门, 2018年1-3月实发工资总额, 2018年4-6月实发工资总额, 2018年7-9月实发工资总额

select dept_name,a.dept_no,total1,total2,total3 from dept d 
join 
(select dept_no,sum(salary+bonus) total1 from emp where year(month-time)=2018 and month(month-time) between 1 and 3
group by a.dept_no) a
on d.dept_no=a.dept_no
join
(select dept_no,sum(salary+bonus) total2 from emp where year(month-time)=2018 and month(month-time) between 4 and 6
group by a.dept_no) b
on d.dept_no=b.dept_no
join 
(select dept_no,sum(salary+bonus) total3 from emp where year(month-time)=2018 and month(month-time) between 7 and 9
group by a.dept_no) c
on d.dept_no=c.dept_no

(2)在财务部,人事部,运营部,各随机取5位员工的员工编号,姓名,职位,基本工资(一条语句)

select emp_no,emp_name,title,salary from emp where dept_no in (select dept_no from dept where dept_name='财务部') order by rand() limit 5
union all
select emp_no,emp_name,title,salary from emp where dept_no in (select dept_no from dept where dept_name='人事部') order by rand() limit 5
union all
select emp_no,emp_name,title,salary from emp where dept_no in (select dept_no from dept where dept_name='运营部') order by rand() limit 5

(3)题目:查询出每个员工的姓名,工资,部门名称,工资在公司的等级及其领导的姓名及其工资所在的等级

select emp name,salary,dept_name,grade,leader,g from emp a join dept b on a.dept_no=b.dept_no 
join grade on salary between losal and hisal join
(select emp_no,emp_name leader,grade g from emp a join grade on salary between losal and hisal ) c on a.mar=c.emp_no

18.已知

表a: 表b:
id name id age
1 zhao 1 30
2 li 2 28
3 wang 4 21

select.id,a.name,b.age from( )on a.id=b.id;
分别写出 join, left join, right join在()时,sql语句的执行结果。
join:

id a.name b.age
1 zhao 30
2 li 28

left join:

id a.name b.age
1 zhao 30
2 li 28
3 wang null

right join

id a.name b.age
1 zhao 30
2 li 28
4 null 21

19.已知表a和表b,编写sql统计ios和 android的用户总点击数 total click(若一次sq无法完成统计,可以使用临时表c、d、e等暂存中间数据,无需实现建表过程,描述清楚表的字段即可)

表a: 表b:
id device id click
1 ios 1 3
2 android 3 4
3 ios 2 3
1 2
4 2

select device,sum(total) from a join (select id,sum(click) from b group by id )c on a.id=c.id group by device
20. 例:数据表

province city sellCount
北京市 朝阳区 100
北京市 朝阳区 200
北京市 朝阳区 111
北京市 西城区 300
北京市 西城区 789
北京市 西城区 310
北京市 东城区 456
北京市 东城区 789
北京市 东城区 111

需求:编写SQL,取每个 city sellCount的top2结果,如下表所示

city sellCount
朝阳区 200
朝阳区 100
东城区 789
东城区 456
西城区 789
西城区 310
select a.city,b.sellCount from sell a 
join sell b on a.city=b.city and a.sellCount<=b.sellCount
group by a.city,a.sellCount having count(b.sellCount)<=2
order by b.sellCount

21.P_ID为产品ID,P_Num为产品库存量S_ID为仓库ID.请用SQL语句实现将上表中的数据合并。

P_ID P_ NUM S_ID
1 10 1
1 12 2
2 8 1
3 11 1
3 8 3

结果如下:S1_ID为仓库1的库存量,S2 _IDd为仓库2的库存量,S3_ID为仓库3的库存量。如果该产品在某仓库中无库存量,那么就是0代替。

P_ID S1_ID S2 _ID S3_ID
1 10 12 0
2 8 0 0
3 11 0 8
子查询的一部分:
select p_id,sum(p_num) s1_id from p p1 where s_id=1 group by p_id
case when 的写法:
select pid,sum(case sid when 1 then p_num else 0 end)s1_id,sum(case sid when 2 then p_num else 0 end)s2_id,sum(case sid when 3 then p_num else 0 end)s3_id from p group by p_id

22.用一条SQL语句查询出每门课都大于80分的学生姓名

Name kecheng fenshu
张三 语文 81
张三 数学 75
李四 语文 76
李四 数学 90
王五 语文 81
王五 数学 100
王五 英语 90

select name from a group by name having min(fenshu)>80;
23.学生表如下

自动编号 学号 姓名 课程编号 分数
1 2005001 张三 0001数学 69
2 2005002 李四 0001 数学 89
3 2005001 张三 0001 数学 69

删除除了自动编号不同,其他都相同的学生冗余信息

select distinct * from a;
delete from a where id not in (select id from a group by stu_no,name,course_id,score);

面试题:

create table work_plan
(
worker_name varchar(10),  --人员
start_date date,                  --派工起始日
end_date date,                   --派工截止日
sign_time varchar(10)         --派工期间的需要打卡时间
)
insert into work_plan values
('张三','2020-01-01',null,'06:30'),
('李四','2020-02-01','2020-02-15','07:00'),
('王五','2019-12-29','2020-03-30','06:00'),
('赵六','2019-12-29','2020-03-30','06:00')

1、表示某人从某日开始到某日结束,按要求工作,派工期间每日打卡时间必须在“要求到岗时间”前(含要求时间,精确到分钟),否则迟到。
例如:
要求7:00,则6:59或者7:00:59 都不算迟到;7:01则视为迟到1分钟
2、行1中“派工结束日期”为null,表示此人的工作结束时间尚未确定,还在搬砖中;
行2中派工结束日期为2020-02-15,表示派工于02-15日结束。
3、假设员工名字不重复,每人只有一条派工信息

create table sign_log
(
worker_name varchar(10),
sign_time datetime
)
insert into sign_log values  
('张三','2020-02-16 04:01'),
('张三','2020-02-16 05:02'),
('张三','2020-02-16 06:03'),
('王五','2020-02-16 07:03'),
('王五','2020-02-16 08:03'),
('王五','2020-02-16 09:03')

打卡记录表
在员工每次按指纹考勤时
都会生成一条记录
一、题目:写一个查询语句,输入参数:日期(date),输出表格如下:

姓名(varchar) 考勤日期(date) 是否迟到 迟到时间(分钟 int)
张三 2020-02-16 0
王五 2020-02-16 63
赵六 2020-02-16 1440

注:
1、2020-02-16李四派工期已结束,不在派工期间不需要计算考勤,故不用显示
2、赵六在当日没有打卡,按照迟到算,迟到时间1440分钟

select a.worker_name,a.sign_time,date(b.sign_time) sign_date,min(time(b.sign_time)) signed,
case when
    b.sign_time is null or a.sign_time

二、另外请模拟以下场景,来写对应的sql语句:
1、某天打卡机异常,需要对公司所有员工当天的考勤统一处理为7:00(注:当天已经打卡的不用处理)

insert into sign_log
select worker_name,'2020-9-12 07:00:00' 
from work_plan 
where end_date is null and worker_name not in 
(select work_name from sign_log where date(sign_time)='2020-9-12') 
or '2020-9-12' between start_date and end_date 
group by a.worker_name;

2、个别人考勤异常(忘打卡),提交补卡单后,人事在考勤系统中处理的sql(注:每个人每个月的补卡次数为3次,超过该次数则不能补卡,请用存过实现流程控制)

你可能感兴趣的:(笔记)