1. 查找最晚入職員工的所有信息 sql CREATE TABLE ( int(11) NOT NULL, date NOT NULL, varchar(14) NOT NULL, varchar(16) NOT NULL, char(1) NOT NULL, date NOT NULL, PRIM ...
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`));
解題思路:根據入職時間倒序排序order by ... DESC
,然後再取一條記錄,就是最晚入職的員工。
select * from employees
order by hire_date DESC limit 1;
這樣做有一個問題,hire_date
是 date 類型,很有可能多條記錄中是同一個時間入職的,所以說時間類型還是用時間戳比較精切。
針對這道題目可以使用 MAX()
函數,然後用一個子查詢。
select * from employees
where hire_date = (select MAX(hire_date) FROM employees);
MAX()
先查詢出最晚入職的時間,然後再查詢出在最晚時間入職的所有員工。
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`));
解題思路:查詢入職時間倒數第三的,要先進行排序,再取三條記錄。MySQL中的結果集預設以正序排列,要逆序排列就要使用 DESC
,取第三條則是使用limit
。
select * from employees
order by hire_date DESC
limit 2,1;
3. 查找當前薪水詳情以及部門編號dept_no
查找各個部門當前(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
做關聯即可。
select s.*, d.dept_no
from salaries s
join dept_manager d on d.emp_no = s.emp_no
where d.to_date='9999-01-01';
上面的SQL有一個優化的點,就是可以用 s.to_date='9999-01-01'
再進行一次去重鎖定。修改之後的 SQL 如下所示:
select s.*, d.dept_no
from salaries s
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';
吐槽:牛客網裡,表
dept_manager
用兩個字母的別名 dm,竟然過不了...
4. 查找所有已經分配部門的員工的last_name和first_name以及dept_no
查找所有已經分配部門的員工的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`));
解題思路:這道題開始想到用一個子查詢,先查詢出所有部門id,作為條件去查詢員工表。然後看到還需要查詢出部門表裡的dept_no
,所以覺得用外連接更加合適,用dept_emp
表作為主表進行查詢。
select e.last_name, e.first_name, d.dept_no
from dept_emp d
left join employees e on d.emp_no=e.emp_no;
5. 查找所有員工的last_name和first_name以及對應部門編號dept_no
查找所有員工的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`));
解題思路:這個和上一題一個意思,只是這題里,沒有部門號的也要查詢出來,即查詢所有員工,以員工表作為主表。
select e.last_name, e.first_name, d.dept_no
from employees e
left join dept_emp d on d.emp_no=e.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`));
解題思路:這道題要考慮到,員工的入職時的薪水情況,即他入職第一個月時的薪水,即employees.hire_date=salaries.from_date
。
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;
7. 查找薪水漲幅超過15次的員工號emp_no以及其對應的漲幅次數t
查找薪水漲幅超過15次的員工號emp_no以及其對應的漲幅次數t
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`)
);
解題思路:看到這道題第一反應是,這道題也太複雜了。因為薪水漲幅需要比較前後兩個月的薪水,如果薪水下降是不能算漲幅的。所以,用解題的思路,我覺得這道題不會這麼複雜,就大膽假設它預設一直漲薪的。
從應試的角度,我覺得它是要考察 group by...having...
,也就是先通過 emp_no 進行分組,再過濾分組記錄數大於15的記錄。
select emp_no, count(emp_no) as t
from salaries
group by emp_no
having t > 15;
果然是這樣。不用糾結這道題的題意,知道考察點在group by...having...
就行了。
8. 找出所有員工當前薪水salary情況
找出所有員工當前(to_date='9999-01-01')具體的薪水salary情況,對於相同的薪水只顯示一次,並按照逆序顯示
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`));
解題思路:這道題講到了,相同的薪水只顯示一次,就是讓我們用 DISTINCT
去重。
select DISTINCT salary
from salaries
where to_date='9999-01-01'
order by salary DESC;
9. 獲取所有部門當前manager的當前薪水情況,給出dept_no, emp_no以及salary,當前表示to_date='9999-01-01'
獲取所有部門當前manager的當前薪水情況,給出dept_no, emp_no以及salary,當前表示to_date='9999-01-01'
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
,dept_no
是dept_manager
表的主鍵,這就表示一個部門可能有多個領導,然後dept_manager
去關聯salaries
表查詢工資即可,限制條件是查詢當天的工資 s.to_date='9999-01-01';
。
select d.dept_no, d.emp_no, s.salary
from dept_manager d
join salaries s on d.emp_no = s.emp_no
where s.to_date='9999-01-01';
但是我這樣寫,竟然AC不過,導入數據後發現,查詢結果是這樣的,意思就是一個部門的一個領導,在同一天會有多份工資??
d001 10002 72527
d001 10002 72527
d001 10002 72527
d001 10002 72527
d001 10002 72527
d001 10002 72527
d004 10004 40054
d004 10004 42283
d004 10004 42542
d004 10004 46065
d004 10004 48271
d004 10004 50594
d004 10004 52119
d004 10004 54693
d004 10004 58326
要再加一個查詢條件d.to_date='9999-01-01'
,看討論說是表示在職的經理。
select d.dept_no, d.emp_no, s.salary
from dept_manager d
join salaries s on d.emp_no = s.emp_no
where s.to_date='9999-01-01' and d.to_date='9999-01-01';
10. 獲取所有非manager的員工emp_no
獲取所有非manager的員工emp_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 `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`));
解題思路:查找不是 Manager 的員工,即 employees 左連接 dept_manager 之後,沒有在 dept_manager 表中查詢到記錄的員工。所以在關聯之後,判斷 d.dept_no IS NULL;
就是在 dept_manager
表中沒有數據的員工了。
select e.emp_no
from employees e
left join dept_manager d on e.emp_no = d.emp_no
where d.dept_no IS NULL;