数据结构和算法 II
面试题
(1) 用户表中添加一条数据,请写出SQL语句
insert into user values(1,'tom','男',23,'2022-12-12',1)
(2) 在用户表中把姓名为"李四"的在职用户的年龄修改为28
update user set age=28,sex='女' where name='李四' and state=1
(3) 查询所有的角色名称为"技术人员",性别是女的在职人员
select u.* from role r join user_role ur join user u on r.id=ur.role_id and ur.user_id=u.id where r.name='技术人员' and sex='女' and state=1
(4) 把角色名称为"研发人员"的用户"张三"从用户表中删除
delete from user where id in
(select u.id from role r join user_role ur join user u on r.id=ur.role_id and ur.user_id=u.id where r.name='研发人员' and u.name='张三')
(5) 查询年龄在18到24岁之间的男性在职人员
select * from user where age between 18 and 24 and sex='男' and state=1
(6)查询年龄为18,19,20的男性和女性员工的人数,结果如下图所示:
年龄 | 男 | 女 |
---|---|---|
18 | 5 | 3 |
19 | 4 | 6 |
20 | 1 | 0 |
select age,
sum(case when stu_gender='男' then 1 else 0 end)'男',
sum(case when stu_gender='女' then 1 else 0 end)'女'
from student where age between 18 and 20 group by age
(7) 查询前50名姓张的男员工
select * from user where name like'张%' and sex='男' limit 50
(8)查询所有根角色员工,根角色就是父角色为null的角色.
select u.* from role r join user_role ur join user u on r.id=ur.role_id and ur.user_id=u.id where parentId is null
9. 以下四个表,表名称及表结构如下:
student(sno,sname,sage,ssex) 学生表
course(cno,cname,tno) 课程表
sc(sno,cno,score) 成绩表
teacher(tno,tname) 教师表
-
查询课程1的成绩比课程2的成绩高的所有学生的信息
select s.*,sc1.score '课程1',sc2.score '课程2' from sc sc1 join sc sc2 join student s on sc1.sno=sc2.sno and sc1.sno=s.sno where sc1.cno=1 and sc2.cno=2 and sc1.score>sc2.score 使用表的自连接查询 select s.*,sc1.score,sc2.score from student s join (select * from sc where cno=1)sc1 join (select * from sc where cno=2)sc2 on sc1.sno=sc2.sno and sc1.sno=s.sno where sc1.score>sc2.score
-
查询平均成绩大于60分的同学的学号和平均成绩
select sno,avg(score) av from sc group by sno having av>60
-
查询学过‘李四’老师所教课程的所有同学的学号,姓名
select distinct s.sno,sname from teacher t join course c join sc join student s on t.tno=c.tno and c.cno=sc.cno and sc.sno=s.sno where tname='李四'
-
查询姓“李”得老师的个数
select count(*) from teacher where tname like '李%'
-
查询每门课程的选修人数(课程名称,学生数量)–存在没有人选的课程
select cname,count(sno) from course c left join sc on c.cno=sc.cno group by c.cno
-
删除“1002”同学的“1”课程的成绩
delete from sc where sno='1002' and cno=1
-
查询选修人数最多的课程(课程id,课程名称,学生数量)–考虑有多门课程都是选修最多的情况
1. 先查询选修人数最多的人数是多少 select count(sno) cou from sc group by cno order by cou desc limit 1 2. 统计每门课程的人数,筛选人数=上述值的课程 select c.cno,cname,count(sno) co from course c join sc on c.cno=sc.cno group by sc.cno having co=(select count(sno) cou from sc group by cno order by cou desc limit 1)
10. 数据库表名为guest,请简答
账号 | 消费 | 时间 | 金额 | 班次 |
---|---|---|---|---|
accounts | details | date | money | class |
s0001 | 房费 | 2020-01-01 | 280 | 001 |
s0001 | 酒水 | 2020-01-02 | 120 | 001 |
s0001 | 房费 | 2020-01-08 | 300 | 003 |
s0002 | 酒水 | 2020-01-29 | 50 | |
s0003 | 房费 | 2020-01-31 | 180 | 002 |
s0004 | 房费 | 2020-02-01 | 230 | 001 |
s0005 | 酒水 | 2020-02-01 | 100 | |
s0005 | 房费 | 2020-02-02 | 128 | 001 |
-
查询出房费都大于200的账号
思路:统计每个账号房费的最低消费金额,筛选最低消费金额大于200的账号 select accounts from guest where details='房费' group by accounts having min(money)>200
-
查询出3月份每个账号酒水和房费的总金额
日期函数 year(col) month(col) day(col) 前提:col的类型为 date datetime hour(col):前提col的数据类型必须是time、datetime minute(col) second(col) date(col) --eg: col类型是datetime time(col) 以上函数可以放在select后面 可以放在查询条件部分 where select accounts,sum(money) from guest where month(date)=3 group by accounts
-
将不是房费的班次都更改为‘001’
update guest set class='001' where details!='房费'
-
查询出消费都大于100的账号
select accounts from guest group by accounts having min(money)>100
3. 完成以下sql查询
下面是学生成绩表(student_score)结构说明
字段名称 | 字段解释 | 字段类型 | 字段长度 |
---|---|---|---|
student_id | 学号 | 字符 | 8 |
student_name | 姓名 | 字符 | 50 |
student_gender | 性别 | 字符(男/女) | 4 |
course_id | 课程号 | 字符 | 5 |
score | 分数 | 数值 | 3 |
ismakeup | 当前考试是否为补考 | 字符(补考:1;非补考:0) | 2 |
下面是课程表(course)说明
字段名称 | 字段解释 | 字段类型 | 字段长度 | 约束 |
---|---|---|---|---|
course_id | 课程号 | 字符 | 5 | PK |
course_name | 课程名 | 字符 | 30 | Not null |
course_desc | 课程介绍 | 字符 | 60 |
1、查找第一次考试后所有需要补考(小于60分)的学生姓名和这门课程的名称和成绩;
select student_name,course_name,score from student_score ss join course c on ss.course_id=c.course_id where is_makeup=0 and score<60
2、查询每个学生第一次考试后需要补考(小于60分)的课程平均分和科目数
select student_id,student_name,count(course_id)'科目数',avg(score)'平均分' from student_score where is_makeup=0 and score<60 group by student_id
3、查询所有参加了补考的学生的学生姓名,课程名称,补考成绩和非补考成绩;
思路:将成绩表当成2份,两个成绩表进行联查,从其中一张成绩表查询补考成绩,从另一张成绩表查询这个学生这门课程的非补考成绩 -- 自连接查询
select sc0.student_name,course_name,sc1.score'补考成绩',sc0.score'非补考成绩' from student_score sc0 join student_score sc1 join course c on sc0.student_id=sc1.student_id and sc0.course_id=sc1.course_id and sc0.course_id=c.course_id where sc0.is_makeup=0 and sc1.is_makeup=1
6. 有如下表:
emp:
empno int(员工编号) ,ename varchar(50)(员工姓名) ,job varchar(100) (工作岗位),mgr int (上级领导编号),hiredate date(雇佣日期),sal int(薪金),comm int(佣金) deptno int (部门编号)
提示:工资=薪金+佣金
dept表:
deptno int (部门编号) , dname 部门名称 loc 地点
-
列出在每个部门工作的员工数量,平均工资
select d.id,d.name,count(e.id)'员工数量',avg(salary+comm)'平均工资' from dept d left join employee e on d.id=e.dept_id group by d.id
-
列出所有员工的姓名,部门名称和工资
select e.name,d.name,salary+comm '工资' from employee e join dept d on e.dept_id=d.id
-
列出所有部门的详细信息和部门人数
select d.id,d.name,count(e.id) from dept d left join employee e on d.id=e.dept_id group by d.id
-
列出各种工作的最低工资
select job,min(salary+comm) from employee group by job
-
列出各个部门的manager的最低薪金(若是manager,其job的值为manageer)
select d.id,d.name,min(salary) from employee e join dept d on e.dept_id=d.id where job='manager' group by e.dept_id
-
列出受雇日期早于其直接上级的所有员工
思路:使用表的自连接查询 select e1.id,e1.name,e1.hiredate,e2.id,e2.name,e2.hiredate from employee e1 join employee e2 on e1.mgr_id=e2.id where e1.hiredate<e2.hiredate
-
列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门
select d.name,e.id,e.name,e.dept_id from dept d left join employee e on d.id=e.dept_id
-
列出所有‘clerk’(办事员)岗位的姓名以及部门名称
select e.name,d.name from dept d join employee e on d.id=e.dept_id where job='clerk'
-
列出最低薪金大于6500的各种工作
统计每种工作的最低薪金,筛选最低薪金大于6500的 select job from employee group by job having min(salary)>6500
-
列出在研发部工作的员工的姓名,假定不知道研发部的部门编号
select e.name from employee e join dept d on e.dept_id=d.id where d.name='研发部'