質問

私は分析関数での作業に新たなんです。

DEPT EMP   SALARY
---- ----- ------
  10 MARY  100000
  10 JOHN  200000
  10 SCOTT 300000
  20 BOB   100000
  20 BETTY 200000
  30 ALAN  100000
  30 TOM   200000
  30 JEFF  300000

私は最低賃金との部門と従業員を望んでます。

結果は次のようになります。

DEPT EMP   SALARY
---- ----- ------
  10 MARY  100000
  20 BOB   100000
  30 ALAN  100000

編集:ここで私は(それは同様GROUP BY句でスタッフを望んでいるとしてではなく、もちろん、それは動作しません)しているSQLがあります:

SELECT dept, 
  emp,
  MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY salary)
FROM mytable
GROUP BY dept
役に立ちましたか?

解決

私はランク()関数は、2つの理由から、これを移動するための方法ではないと思われる。

まず、それはおそらく、MIN()よりも効率が低い - ベースの方法

この理由は、クエリは、それがデータをスキャンし、ランクが再度読み、このリストによって、後に割り当てられますよう、部門ごとに、すべての給与の順序付けられたリストを維持しなければならないということです。明らかにこれのために活用することができるインデックスが存在しない場合に、最後のデータ項目が読み込まれるまで、あなたはランクを割り当てることはできませんし、リストのメンテナンスは高価であります。

ランク()関数の性能がスキャンされる要素の総数に依存し、したがって、数がディスクにソート流出は、パフォーマンスが崩壊することが十分である場合。

これはおそらく、より効率的です。

select dept,
       emp,
       salary
from
       (
       SELECT dept, 
              emp,
              salary,
              Min(salary) Over (Partition By dept) min_salary
       FROM   mytable
       )
where salary = min_salary
/

このメソッドは、クエリがこれまでに遭遇した最小値の部門ごとに単一の値を維持することが必要です。新しい最小に遭遇した場合、既存の値が変更され、そうでない場合、新しい値は破棄されます。メモリに保持されなければならない要素の総数は、部署の数ではなく、スキャンされた行の数に関連している。

これは、Oracleがランクは本当にこのケースで計算する必要はありませんが、私はそれに賭けるしないことを認識するためにコードパスを持っている可能性があります。

()ランクを嫌うための第二の理由はそれだけで間違った質問に答えることです。質問は、それが「どのレコードが部門ごとに最小で給料を持っている」ある「どのレコードは、部門ごとの給与が発注昇順されている最初のランキングがある給料を持っている」ではありません。それは、少なくとも、私には大きな違いになります。

他のヒント

私はあなたの元のクエリとかなり接近していたと思います。以下は実行して、テストケースに一致するだろう。

SELECT dept, 
  MIN(emp) KEEP(DENSE_RANK FIRST ORDER BY salary, ROWID) AS emp,
  MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY salary, ROWID) AS salary
FROM mytable
GROUP BY dept

RANKとは対照的に()ソリューション、これは、部門ごとに最大1つの行に保証します。しかし、それは問題でヒント:何が最低給与上の二人の従業員がある部署になりますか? RANK()ソリューションは、両方の従業員を返します - 部門のための複数の行を。この答えは、任意に1を選択し、部門の一つだけがありますことを確認します。

あなたはRANK()構文を使用することができます。従業員が自分の給料がどのように大規模に関しては、部門内にランクどこたとえば、このクエリはあなたを教えてくれます。

SELECT
  dept,
  emp,
  salary,
  (RANK() OVER (PARTITION BY dept ORDER BY salary)) salary_rank_within_dept
FROM EMPLOYEES

あなたは、この場所salary_rank_within_dept = 1から問い合わせることができ

SELECT * FROM
  (
    SELECT
      dept,
      emp,
      salary,
      (RANK() OVER (PARTITION BY dept ORDER BY salary)) salary_rank_within_dept
    FROM EMPLOYEES
  )
WHERE salary_rank_within_dept = 1
select e2.dept, e2.emp, e2.salary
from employee e2
where e2.salary = (select min(e1.salary) from employee e1)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top