我正在尝试通过使用基于连接表的条件来找到过滤行的最佳方法。举个例子,我根据每个员工的工资等级加入员工和薪资等级表。然后我想只显示与某个员工(Blake)具有相同等级的员工。我使用了以下代码:
SELECT e.ename, e.sal, sg.grade
FROM emp e JOIN salgrade sg
ON(e.sal BETWEEN sg.losal AND sg.hisal)
WHERE sg.grade = (SELECT sg.grade FROM emp e JOIN salgrade sg ON(e.sal BETWEEN sg.losal AND sg.hisal) WHERE e.ename = 'BLAKE')
ORDER BY e.sal DESC
是否有更优化的方式来编写查询?
答案 0 :(得分:0)
这是一种使用窗口函数的方法:
SELECT es.*
FROM (SELECT e.ename, e.sal, sg.grade,
MAX(CASE WHEN e.ename = 'BLAKE' THEN sg.grade END) OVER () as blake_grade
FROM emp e JOIN
salgrade sg
ON e.sal BETWEEN sg.losal AND sg.hisal
) es
WHERE grade = blake_grade
ORDER BY e.sal DESC;
答案 1 :(得分:0)
我不会在WHERE子句中的select中使用连接;相反,我会使用内部标量子查询来获取BLAKE的工资,然后使用外部标量子查询来获取他的salgrade。否则与您的查询非常相似:
select e.ename, e.sal, s.grade
from emp e inner join salgrade s on e.sal between s.losal and s.hisal
where s.grade = ( select grade
from salgrade
where (select sal from emp where ename = 'BLAKE')
between losal and hisal
)
order by sal desc
;
使用相同的想法,你也可以取消第一次加入(通过返回BLAKE的losal
和hisal
以及他的salgrade
),但也许这是太过分了。
答案 2 :(得分:0)
如果这只是不必两次编写相同的代码,您可以使用WITH
子句:
WITH emps_and_sals AS
(
SELECT e.ename, e.sal, sg.grade
FROM emp e
JOIN salgrade sg ON e.sal BETWEEN sg.losal AND sg.hisal
)
SELECT *
FROM emps_and_sals
WHERE grade = (SELECT grade FROM emps_and_sals WHERE ename = 'BLAKE')
ORDER BY sal DESC;