淺談DQL之“相等問題”

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);

emp

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 都要考慮清楚,到底應該是哪些字段,保證同步

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章