2016-11-30 222 views
0

我想通过使用基于连接表的条件来筛选出行的最佳方法。作为一个例子,我根据每位员工的工资等级加入员工和工资等级表。然后,我只想显示与某位员工(布莱克)具有相同等级的员工。我使用下面的代码:在连接表上使用WHERE子句

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

什么数据库系统,您使用的? SQL Server,Oracle,MySQL? –

+0

我使用Oracle * –

+0

我们能否看到来自两个表的一些示例数据? – VDK

回答

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; 
+0

是的,这正是我想要做的,但这超出了我目前的课程范围。也许我做这件事的方式可能是用我想到的东西去解决它的唯一方法。 –

0

我不会用在选择的联接WHERE子句;相反,我会使用内部标量子查询来获取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 
; 

使用相同的想法,你可能会在第加盟以及做掉(通过返回布雷克的losalhisal以及他salgrade),但也许这就是服用它太过分了。

+0

这正是我所寻找的,更不要说随意性。我不喜欢我的代码的事情是,我在子查询中使用连接,出于某种原因,我想不出使用连接表来找到它。无论如何,谢谢! –

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;