个人提交答案汇总,part3
解答比较繁琐有建议或好的想法欢迎评论区指出探讨=w=
1-20 答案链接在这里
21-40 答案链接在这里
41、构造一个触发器audit_log,在向employees_test表中插入一条数据的时候,触发插入相关的数据到audit中。
create trigger audit_log after insert on employees_test for each row
begin
insert into audit values (new.id, new.name);
end
42、删除emp_no重复的记录,只保留最小的id对应的记录。
delete from titles_test where id not in (
select a.min_id from (
select min(id) as min_id from titles_test
group by emp_no
) a
) ;
43、将所有to_date为9999-01-01的全部更新为NULL,且 from_date更新为2001-01-01。
update titles_test set to_date = NULL , from_date = '2001-01-01';
- update 更新一列/多列的方法:
UPDATE Person SET FirstName = 'Fred' WHERE LastName = 'Wilson'
UPDATE Person SET Address = 'Zhongshan 23', City = 'Nanjing' WHERE LastName = 'Wilson'
44、将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005,其他数据保持不变,使用replace实现,直接使用update会报错。
replace into titles_test
values (5, 10005, 'Senior Engineer', '1986-06-26', '9999-01-01')
- 使用replace语句要注意:replace操作的过程是有冲突时先删除原有的有冲突的记录再插入新的记录,所以对于记录没有插入数据的字段的值是null,因此不能直接写为:
replace into titles_test(id, emp_no) values (5, 10005)
45、将titles_test表名修改为titles_2017
alter table titles_test rename to titles_2017;
- mysql语法to可以省略
46、在audit表上创建外键约束,其emp_no对应employees_test表的主键id。
alter table audit
add constraint FK_audit
foreign key (emp_no)
references employees_test(id);
- 添加约束:
- 添加主键约束
ALTER TABLE table1_name ADD CONSTRAINT PK_id PRIMARY KEY (id);
- 添加外键约束
ALTER TABLE table2_name ADD CONSTRAINT FK_id FOREIGN KEY(id) REFERENCES table1_name(id)
- 添加唯一约束
ALTER TABLE table_name ADD UNIQUE (id);
- 添加/删除默认约束
ALTER TABLE table_name ALTER col_name {SET DEFAULT | DROP DEFAULT};
- 删除约束
ALTER TABLE table_name DROP [FOREIGN KEY|PRIMARY KEY] name;
48、请你写出更新语句,将所有获取奖金的员工当前的(salaries.to_date=‘9999-01-01’)薪水增加10%。
update salaries
set salary = salary*1.1
where to_date = '9999-01-01'
and emp_no in (select emp_no from emp_bonus)
50、将employees表中的所有员工的last_name和first_name通过(’)连接起来
select concat(last_name,"'",first_name)
from employees
select concat_ws("'",last_name,first_name)
from employees
- 这两种方法都行,第二个concat_ws函数是先把分隔符写在最前面,和concat函数不同的是,concat_ws函数在执行的时候,不会因为NULL值而返回NULL
51、查找字符串’10,A,B’ 中逗号’,'出现的次数cnt。
select length("10,A,B")-length(replace("10,A,B",",",""))
这道题以前没有遇到过类似需求的,百度了下,看到有小伙伴这样写觉得很厉害,思路很好。
当遇到子串长度不为1的时候,记得除以字串的长度,写出下面这样length("10,A,B")-length(replace("10,A,B",",",""))/length(",")
52、获取Employees中的first_name,查询按照first_name最后两个字母,按照升序进行排列
select first_name
from employees
order by right(first_name, 2)
53、按照dept_no进行汇总,属于同一个部门的emp_no按照逗号进行连接,结果给出dept_no以及连接出的结果employees
select dept_no as dept_no
,group_concat(emp_no) as employees
from dept_emp
group by dept_no
- group_concat(X),group_concat(X,Y)
- group_concat()函数返回X的非null值的连接后的字符串。如果给出了参数Y,将会在每个X之间用Y作为分隔符。如果省略了Y,“,”将作为默认的分隔符。每个元素连接的顺序是随机的。
54、查找排除最大、最小salary之后的当前(to_date = ‘9999-01-01’ )员工的平均工资avg_salary。
select avg(salary) from salaries
where salary not in(
select max(salary) as max_salary from salaries where to_date = "9999-01-01")
and salary not in (
select min(salary) as min_salary from salaries where to_date = "9999-01-01")
and to_date = "9999-01-01"
也可以不用not in,使用大于最小值,小于最大值来判断
select avg(salary) from salaries
where salary < (
select max(salary) as max_salary from salaries where to_date = "9999-01-01")
and salary > (
select min(salary) as min_salary from salaries where to_date = "9999-01-01")
and to_date = "9999-01-01"
55、分页查询employees表,每5行一页,返回第2页的数据
select * from employees limit 5,5
select * from employees limit 5 offset 5
从第五行开始,查询五行数据,offset也可以,偏移五行,我习惯用第一种了
57、使用含有关键字exists查找未分配具体部门的员工的所有信息。
select * from employees
where not exists
(select emp_no from dept_emp where employees.emp_no = dept_emp.emp_no)
- in:先执行子查询,得到一个结果集,将结果集代入外层谓词条件执行主查询,子查询只需要执行一次
- exists:先从主查询中取得一条数据,再代入到子查询中,执行一次子查询,判断子查询是否能返回结果,主查询有多少条数据,子查询就要执行多少次
58、获取有奖金的员工相关信息。
select employees.emp_no
,employees.first_name
,employees.last_name
,emp_bonus.btype
,salaries.salary
,case emp_bonus.btype when '1' then 0.1 * salaries.salary
when '2' then 0.2 * salaries.salary
else 0.3 * salaries.salary end as bonus
from employees, emp_bonus, salaries
where employees.emp_no = emp_bonus.emp_no and employees.emp_no = salaries.emp_no
and emp_bonus.emp_no = salaries.emp_no
and salaries.to_date = "9999-01-01"
60、按照salary的累计和running_total,其中running_total为前N个当前( to_date = ‘9999-01-01’)员工的salary累计和,其他以此类推
select emp_no
,salary
,sum(salary)
over(order by emp_no)
as running_total
from salaries
where to_date = "9999-01-01"
牛客评论区有个小伙伴是这样写的,记一下,这个思路也很棒
select a.emp_no, a.salary, sum(b.salary)
from salaries as a, salaries as b
where b.emp_no <= a.emp_no
and a.to_date = '9999-01-01'
and b.to_date = '9999-01-01'
group by a.emp_no
order by a.emp_no asc