数据库SQL线上笔试编程题Ⅰ(练习向)

1.查找入职员工时间排名倒数第三的员工所有信息

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`));
emp_no birth_date first_name last_name gender hire_date
10005 1955-01-21 Kyoichi Maliniak M 1989-09-12

MyCode:

select * from employees
where hire_date = (
    select distinct hire_date 
    from employees 
    order by hire_date DESC limit 2, 1
)
# 1.考虑到排在第三的不止一个人;
# 2.考虑去重使用distinct
# 知识点limit
LIMIT m,n : 表示从第m+1条开始,取n条数据;
LIMIT n : 表示从第0条开始,取n条数据,是limit(0,n)的缩写。

2. 查找最晚入职员工的所有信息

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`));
emp_no birth_date first_name last_name gender hire_date
10005 1955-01-21 Kyoichi Maliniak M 1989-09-12
SELECT * FROM employees
    WHERE hire_date = (
    SELECT MAX(hire_date) 
    FROM employees
)

3.查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号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`));
emp_no salary from_date to_date dept_no
10002 72527 2001-08-02 9999-01-01 d001
10004 74057 2001-11-27 9999-01-01 d004
10005 94692 2001-09-09 9999-01-01 d003
10006 43311 2001-08-02 9999-01-01 d002
10010 94409 2001-11-23 9999-01-01 d006

MyCode:

SELECT s.* , d.dept_no
FROM salaries AS s 
JOIN dept_manager AS d 
ON s.emp_no = d.emp_no
WHERE s.to_date = '9999-01-01' AND d.to_date='9999-01-01';
POINT!
# 这里的坑主要在于两个表的逻辑关系,题目要求是薪水情况以及部门编号,
# 再结合输出情况dept_no 被放到了最后一列,可见是主表是“salaries”。
# 这里顺序错了就会提示:您的代码无法通过所有用例
such as...
select salaries.emp_no, salaries.salary, salaries.from_date, salaries.to_date, dept_manager.dept_no 
from salaries inner join dept_manager
on dept_manager.emp_no = salaries.emp_no
where dept_manager.to_date = '9999-01-01' 
and salaries.to_date = '9999-01-01';

--------------------------

select salaries.emp_no, salaries.salary, salaries.from_date, salaries.to_date, dept_manager.dept_no 
from dept_manager  inner join salaries
on dept_manager.emp_no = salaries.emp_no
where dept_manager.to_date = '9999-01-01' 
and salaries.to_date = '9999-01-01';

---------------------------
只是换了一下表的顺序,上面的能成功,下面的却失败

4.查找所有已经分配部门的员工的last_name和first_name

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 `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`));
last_name first_name dept_no
Facello Georgi d001
省略 省略 省略
Piveteau Duangkaew d006
POINT!
IF按TABLE employees中顺序输出的
使用 <内连接> 查询时,必须将employees表放在前面。
SELECT e.last_name, e.first_name, d.dept_no 
FROM employees e, dept_emp d
WHERE d.emp_no = e.emp_no;
POINT!
使用 <左连接查询> 时
TABLE employees中没有分配部门的员工(没有被记录在dept_emp表)
dept_no字段被自动取NULL然后被输出
所以应当剔除(复合条件连接查询)
SELECT last_name, first_name, dept_no
FROM dept_emp d LEFT JOIN employees e
ON e.emp_no = d.emp_no
WHERE d.dept_no != '';
# POINT: JOIN
INNER JOIN 两边表同时有对应的数据,即任何一边缺失数据就不显示;
LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据;
RIGHT JOIN 会读取右边数据表的全部数据,即便左边表无对应数据。

5.查找所有员工的last_name和first_name以及对应部门编号dept_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 `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`));

EX. POINT:注意最后一个例子!

last_name first_name dept_no
Facello Georgi d001
省略 省略 省略
Sluis Mary NULL(在sqlite中此处为空,MySQL为NULL)

MyCode:

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

6.查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序

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 `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`));
emp_no salary
10011 25828
省略 省略
10001 60117

POINT!

1,由于测试数据中,salaries.emp_no不唯一(因为号码为emp_no的员工会有多次涨薪的可能,所以在薪水中对应的记录不止一条),employees.emp_no唯一,即salaries的数据会多于员工,因此需先找到employees.emp_no在薪水表中对应的记录salaries.emp_no,则有限制条件e.emp_no = s.emp_no

2,根据题意注意到salaries.from_date和employees.hire_date的值应该要相等,因此有限制条件 e.hire_date = s.from_date

3,根据题意要按照emp_no值逆序排列,因此最后要加上 ORDER BY e.emp_no DESC

4,为了代码良好的可读性,运用了Alias别名语句,将员工简化为e,薪水简化为s,即 员工AS e与工资AS,其中AS可以省略

方法一:利用INNER JOIN连接两张表
SELECT e.emp_no, s.salary FROM employees AS e INNER JOIN salaries AS s
ON e.emp_no = s.emp_no AND e.hire_date = s.from_date
ORDER BY e.emp_no DESC

方法二:直接用逗号并列查询两张表
SELECT e.emp_no, s.salary FROM employees AS e, salaries AS s
WHERE e.emp_no = s.emp_no AND e.hire_date = s.from_date
ORDER BY e.emp_no DESC

MyCode:

SELECT e.emp_no, s.salary
FROM employees e JOIN salaries s
ON e.emp_no = s.emp_no 
AND e.hire_date = s.from_date
ORDER BY e.emp_no DESC

你可能感兴趣的:(数据库SQL线上笔试编程题Ⅰ(练习向))