ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

牛客网-数据库61题做题打卡(1-10题)

2020-06-07 15:06:15  阅读:439  来源: 互联网

标签:10 01 no employees dept 做题 emp date 打卡


建表准备

create database nk_exe;
use nk_exe;
CREATE TABLE `employees` (
  `emp_no` INT (11) NOT NULL,
  `birth_date` DATE NOT NULL,
  `first_name` VARCHAR (14) NOT NULL,
  `last_name` VARCHAR (16) NOT NULL,
  `gender` CHAR(1) NOT NULL,
  `hire_date` DATE NOT NULL,
  PRIMARY KEY (`emp_no`)
) ;
CREATE TABLE `dept_emp` (
  `emp_no` INT (11) NOT NULL,
  `dept_no` CHAR(4) NOT NULL,
  `from_date` DATE NOT NULL,
  `to_date` DATE NOT NULL,
  PRIMARY KEY (`emp_no`, `dept_no`)
) ;
CREATE TABLE `dept_manager` (
  `dept_no` CHAR(4) NOT NULL,
  `emp_no` INT (11) NOT NULL,
  `from_date` DATE NOT NULL,
  `to_date` DATE NOT NULL,
  PRIMARY KEY (`emp_no`, `dept_no`)
) ;

CREATE TABLE `salaries` (
  `emp_no` INT (11) NOT NULL,
  `salary` INT (11) NOT NULL,
  `from_date` DATE NOT NULL,
  `to_date` DATE NOT NULL,
  PRIMARY KEY (`emp_no`, `from_date`)
) ;

CREATE TABLE `departments` (
  `dept_no` CHAR(4) NOT NULL,
  `dept_name` VARCHAR (40) NOT NULL,
  PRIMARY KEY (`dept_no`)
) ;
INSERT INTO dept_manager VALUES('d001',10002,'1996-08-03','9999-01-01');
INSERT INTO dept_manager VALUES('d002',10006,'1990-08-05','9999-01-01');
INSERT INTO dept_manager VALUES('d003',10005,'1989-09-12','9999-01-01');
INSERT INTO dept_manager VALUES('d004',10004,'1986-12-01','9999-01-01');
INSERT INTO dept_manager VALUES('d005',10010,'1996-11-24','2000-06-26');
INSERT INTO dept_manager VALUES('d006',10010,'2000-06-26','9999-01-01');

INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');
INSERT INTO employees VALUES(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');
INSERT INTO employees VALUES(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12');
INSERT INTO employees VALUES(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02');
INSERT INTO employees VALUES(10007,'1957-05-23','Tzvetan','Zielinski','F','1989-02-10');
INSERT INTO employees VALUES(10008,'1958-02-19','Saniya','Kalloufi','M','1994-09-15');
INSERT INTO employees VALUES(10009,'1952-04-19','Sumant','Peac','F','1985-02-18');
INSERT INTO employees VALUES(10010,'1963-06-01','Duangkaew','Piveteau','F','1989-08-24');
INSERT INTO employees VALUES(10011,'1953-11-07','Mary','Sluis','F','1990-01-22');


  • 1、查找最晚入职员工的所有信息
SELECT 
  * 
FROM
  employees 
WHERE hire_date = 
  (SELECT 
    MAX(hire_date) 
  FROM
    employees) ;
  • 2、查找入职员工时间排名倒数第三的员工所有信息
    【注:查找入职员工时间排名倒数第三的员工所有信息,为了减轻入门难度,目前所有的数据里员工入职的日期都不是同一天】
SELECT 
	e.* 
FROM(
	SELECT 
	  emp_no,
	 row_number () over (
	ORDER BY hire_date DESC) AS pm 
	FROM 
	  employees ) r
JOIN employees e ON e.`emp_no`=r.emp_no
where pm=3;
# 本题采用开窗函数-序号函数row_number 显示分区中不重复不间断的序号

  • 3、查找各个部门当前(dept_manager.to_date=‘9999-01-01’)领导当前(salaries.to_date=‘9999-01-01’)薪水详情以及其对应部门编号dept_no
    【注:请以salaries表为主表进行查询,输出结果以salaries.emp_no升序排序,并且请注意输出结果,dept_no列是最后一列】
select 
	s.*,
	d.dept_no
from salaries s
left join dept_manager d on d.emp_no=s.emp_no
where d.to_date='9999-01-01' and s.to_date='9999-01-01';
  • 4、查找所有已经分配部门的员工的last_name和first_name以及dept_no(请注意输出描述里各个列的前后顺序)
select e.last_name,e.first_name,d.dept_no
from dept_emp d 
left join employees e on e.emp_no=d.emp_no

#员工表employees中可能有部分员工无部门(如CEO);
#而部门表dept_emp中正常情况下每个员工都有部门;
  • 5、查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括暂时没有分配具体部门的员工
SELECT 
	e.last_name,
	e.first_name,
	d.dept_no
FROM employees e
LEFT JOIN dept_emp d  ON e.emp_no=d.emp_no;
# 注意区分第4题和第5题题目条件
  • 6、查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序(请注意,一个员工可能有多次涨薪的情况)
select 
	e.emp_no,
	s.salary
from employees e
left join salaries s on e.emp_no=s.emp_no
where e.hire_date=s.from_date
order by e.emp_no desc;

#employees是一表,一个员工可能存在多次涨薪的情况,故将employees作为主表
  • 7、查找薪水变动超过15次的员工号emp_no以及其对应的变动次数t
#方一:
select 
	f_n.* 
from(
	select emp_no,count(*) as t
	from salaries
	group by emp_no) as f_n
where t>15;
#方二:
select 
	emp_no,
	count(*) as t
from salaries
group by emp_no
having t>15;

#注:少用子查询,在数据量大的时候,子查询的效率低下
  • 8、找出所有员工当前(to_date=‘9999-01-01’)具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
select salary
from salaries
where to_date='9999-01-01'
group by salary
order by salary desc;

#对于distinct与group by的使用: 1、当对系统的性能高并数据量大时使用group by 2、当对系统的性能不高时使用数据量少时两者皆可 3、尽量使用group by
  • 9、获取所有部门当前(dept_manager.to_date=‘9999-01-01’)manager的当前(salaries.to_date=‘9999-01-01’)薪水情况,给出dept_no, emp_no以及salary(请注意,同一个人可能有多条薪水情况记录)
select 
	d.dept_no,
	d.emp_no,salary
from dept_manager d
left join salaries s on d.emp_no=s.emp_no
where d.to_date='9999-01-01' and s.to_date='9999-01-01';
#注:同一emp_no在salaries表中对应多条涨薪记录,而当s.to_date = '9999-01-01'时
#是该员工当前的薪水记录
  • 10、获取所有非manager的员工emp_no
select 
	e.emp_no
from employees e
where e.emp_no not in (
	select
		emp_no
	from dept_manager );

以上代码均可在牛客网通过,如有更优代码欢迎交流探讨,若文章有不妥之处,望各位指正。

标签:10,01,no,employees,dept,做题,emp,date,打卡
来源: https://blog.csdn.net/weixin_43288829/article/details/106591231

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有