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
,而後再取一條記錄,就是最晚入職的員工。html
select * from employees order by hire_date DESC limit 1;
這樣作有一個問題,hire_date
是 date 類型,頗有可能多條記錄中是同一個時間入職的,因此說時間類型仍是用時間戳比較精切。mysql
針對這道題目能夠使用 MAX()
函數,而後用一個子查詢。sql
select * from employees where hire_date = (select MAX(hire_date) FROM employees);
MAX()
先查詢出最晚入職的時間,而後再查詢出在最晚時間入職的全部員工。yii
查找入職員工時間排名倒數第三的員工全部信息函數
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;
查找各個部門當前(to_date='9999-01-01')領導當前薪水詳情以及其對應部門編號dept_nocode
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
作關聯便可。htm
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 以下所示:blog
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,居然過不了...排序
查找全部已經分配部門的員工的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;
查找全部員工的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;
查找全部員工入職時候的薪水狀況,給出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;
查找薪水漲幅超過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...
就好了。
找出全部員工當前(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;
獲取全部部門當前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';
獲取全部非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;