문제

나는 새로운 작업과 분석적 기능입니다.

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

편집:여기에는 SQL 가(지의 과정,그것은 작동하지 않으로 원하는 직원 그룹에 의해 절뿐만 아니라):

SELECT dept, 
  emp,
  MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY salary)
FROM mytable
GROUP BY dept
도움이 되었습니까?

해결책

나는 rank () 함수가 두 가지 이유로 이것과 함께 갈 수있는 방법이 아니라고 생각합니다.

첫째, 아마도 최소 ()-기반 방법보다 덜 효율적일 것입니다.

그 이유는 쿼리가 데이터를 스캔 할 때 부서 당 모든 급여 목록을 유지해야하며 나중에이 목록을 다시 읽음으로써 순위가 지정되기 때문입니다. 분명히이를 위해 활용할 수있는 색인이 없으면 마지막 데이터 항목이 읽을 때까지 순위를 할당 할 수 없으며 목록의 유지 보수 비용이 비쌉니다.

따라서 Rank () 함수의 성능은 스캔 할 총 요소의 수에 따라 다르며, 숫자가 디스크로 유출되는 숫자가 충분하면 성능이 붕괴됩니다.

이것은 아마도 더 효율적 일 것입니다 :

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

이 방법은 쿼리가 지금까지 발생하는 최소 값의 부서 당 단일 값을 유지해야합니다. 새 최소값이 발생하면 기존 값이 수정됩니다. 그렇지 않으면 새 값이 폐기됩니다. 메모리에서 보유 해야하는 총 요소 수는 스캔 한 행이 아닌 부서 수와 관련이 있습니다.

Oracle 은이 경우 순위가 실제로 계산 될 필요는 없다는 것을 인식하는 코드 경로를 가지고있을 수 있지만, 내기하지 않을 것입니다.

rank ()를 싫어하는 두 번째 이유는 잘못된 질문에 대답하기 때문입니다. 문제는 "부서 당 급여가 오름차순으로 주문할 때 첫 번째 순위 인 기록이있는 기록에"부서 당 최소 급여가 있습니다 "입니다. 그것은 적어도 나에게 큰 차이를 만듭니다.

다른 팁

나는 당신이 원래 쿼리에 매우 가깝다고 생각합니다. 다음은 실행되고 테스트 사례와 일치합니다.

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 () 솔루션은 부서의 두 직원 이상을 반환합니다. 이 답변은 임의로 하나를 선택하고 부서에 하나만 있는지 확인합니다.

사용할 수 있습니다 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