【SQL】牛客sql题库答案汇总(41-60)

个人提交答案汇总,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);
  • 添加约束:
  1. 添加主键约束
    ALTER TABLE table1_name ADD CONSTRAINT PK_id PRIMARY KEY (id);
  2. 添加外键约束
    ALTER TABLE table2_name ADD CONSTRAINT FK_id FOREIGN KEY(id) REFERENCES table1_name(id)
  3. 添加唯一约束
    ALTER TABLE table_name ADD UNIQUE (id);
  4. 添加/删除默认约束
    ALTER TABLE table_name ALTER col_name {SET DEFAULT | DROP DEFAULT};
  5. 删除约束
    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

你可能感兴趣的:(数据库,mysql,sql,数据库)