0.前言
今天在操作數據庫時遇到了一個挺有意思的問題,特此記錄
1.問題提出
現有一張emp表,表內數據如下
需求:求各部門薪水最高的員工信息
CREATE TABLE emp(
empno INT,
ename VARCHAR(50),
job VARCHAR(50),
mgr INT,
hiredate DATE,
sal DECIMAL(7,2),
comm DECIMAL(7,2),
deptno INT
) ;
INSERT INTO emp VALUES(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp VALUES(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO emp VALUES(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO emp VALUES(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp VALUES(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO emp VALUES(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO emp VALUES(7782,'CLARK','MANAGER',7839,'1981-06-09',3000,NULL,10);
INSERT INTO emp VALUES(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);
INSERT INTO emp VALUES(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO emp VALUES(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO emp VALUES(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);
INSERT INTO emp VALUES(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
INSERT INTO emp VALUES(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);
INSERT INTO emp VALUES(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);
2.問題分析
對於這個問題,其實很簡單
先求各個部門的最高薪資
再求出emp表中薪資等於最高工資的員工信息即可
問題解決
2.1求各個部門的最高薪資
SELECT emp.deptno, MAX(emp.sal) FROM emp
GROUP BY emp.deptno
2. 2求出emp表中薪資等於最高工資的員工信息
SELECT * FROM emp
WHERE emp.sal IN(
SELECT MAX(emp.sal) FROM emp
GROUP BY emp.deptno
)ORDER BY deptno;
很明顯,查詢的結果是錯誤的
3.問題再分析
查詢結果的原因是:薪資和部門不是同時對等,即只比較了薪資,沒有考慮部門這個因素
SELECT MAX(emp.sal) FROM emp
GROUP BY emp.deptno
只能獲取一個最高薪資的集合(5000,3000,2850),然後與emp表中的薪資進行比較,結果就不會正確了。
正確的做法是:讓一個部門所有人的薪資與
該
部門的最高薪資進行對比
4.問題解決
4.1 改進 in
同時考慮部門和薪資,先查詢各個部門的最高薪資對應的 薪資及部門,
再求出emp表中 部門和薪資 同時等於最高薪資的 部門和薪資 的員工信息
SELECT * FROM emp
WHERE(emp.deptno,emp.sal)IN(
SELECT emp.deptno, MAX(emp.sal) FROM emp
GROUP BY emp.deptno
)ORDER BY deptno;
4.2 採用關聯查詢法
先查詢各個部門的最高薪資對應的 薪資及部門,
將查出的結果作爲新表,與emp表關聯查詢。
SELECT e1.* FROM emp e1,
(SELECT emp.deptno, MAX(emp.sal) sal FROM emp
GROUP BY emp.deptno)e2
WHERE e1.deptno=e2.deptno AND e1.sal=e2.sal
ORDER BY e1.deptno;
5.總結
1.查詢時,要充分考慮隱藏的條件
2.無論是關聯查詢,還是集合
的in 都要考慮清楚,到底應該是哪些字段,保證同步