Sie filtern Ihre Abfrage nicht, deshalb werden Ihnen alle Mitarbeiter angezeigt.
Dadurch würden die Mitarbeiter herausgefiltert, die weniger als das Maximum für ihre Abteilung/Besoldungsgruppe verdienen:
SELECT ename, salgrade.grade, dept.dname
FROM emp, salgrade, dept
WHERE emp.sal BETWEEN salgrade.losal AND salgrade.hisal
AND emp.deptno = dept.deptno
AND emp.sal = (SELECT MAX(sal)
FROM emp emp_in, salgrade grade_in
WHERE emp_in.sal BETWEEN grade_in.losal AND grande_in.hisal
AND emp_in.deptno = emp.deptno
AND grade_in.losal = salgrade.losal)
Sie werden immer noch Duplikate finden, weil zum Beispiel zwei Leute im Verkauf das maximale Gehalt für die Besoldungsgruppe 2 verdienen (sowohl Martin als auch Ward verdienen 1250). Entweder ist dies akzeptabel oder Sie benötigen andere Kriterien, um nur eines davon auszuwählen.
Sie können die row_number
verwenden Analysefunktion, um sicherzustellen, dass nur eine Zeile nach Besoldungsgruppe/Abteilung zurückgegeben wird (beachten Sie, dass Oracle willkürlich eine Zeile auswählt, wenn es Duplikate gibt):
SELECT * FROM (
SELECT ename, salgrade.grade, dept.dname,
row_number() OVER (PARTITION BY dept.deptno, salgrade.grade
ORDER BY emp.sal DESC) rnk
FROM emp, salgrade, dept
WHERE emp.sal BETWEEN salgrade.losal AND salgrade.hisal
AND emp.deptno = dept.deptno
) WHERE rnk = 1;
ENAME GRADE DNAME RNK
---------- ------ -------------- ---
MILLER 2 ACCOUNTING 1
CLARK 4 ACCOUNTING 1
KING 5 ACCOUNTING 1
ADAMS 1 RESEARCH 1
FORD 4 RESEARCH 1
JAMES 1 SALES 1
MARTIN 2 SALES 1
ALLEN 3 SALES 1
BLAKE 4 SALES 1