2016-11-30 20 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 

クエリを書くための最適な方法はありますか?

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

あなたはどのようなデータベースシステムを使用しているの? SQL Server、Oracle、MySQL? –

+0

私はOracleを使用しています* –

+0

両方のテーブルのサンプルデータをご覧ください。 – VDK

答えて

0

は、ウィンドウ関数を使用する一つの方法ですむしろ、私はBLAKEの給与をピックアップするために内側のスカラーサブクエリを使用し、次にそのサラウンドをピックアップするために外側のスカラーサブクエリを使用します。そうでなければ、あなたのクエリに非常によく似:

同じ考えを使用して
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 BLAKEのためだけでなく、彼のsalgradeを返すことによって)にも参加して離れて行うことができますそれはあまりにも遠すぎる。

+0

これはまさに私がやろうとしていることですが、これは私の現在のコースの範囲を超えています。たぶん私がやったやり方は、私が思っていたものでそれを行う唯一の方法かもしれない。 –

0

私はWHERE句での選択に参加を使用することはありません;:ここ

+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; 
関連する問題