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次,超过该次数则不能补卡,请用存过实现流程控制)