Oracle에서 유지 여부와 상관없이 파티션 분할
파티션에 집계 함수를 적용하는 두 가지 쿼리를 발견했습니다.
저는 이 두 가지 질문 사이에 차이가 있는지 궁금합니다.
SELECT empno,
deptno,
sal,
MIN(sal) OVER (PARTITION BY deptno) "Lowest",
MAX(sal) OVER (PARTITION BY deptno) "Highest"
FROM empl
SELECT empno,
deptno,
sal,
MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) "Lowest",
MAX(sal) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION BY deptno) "Highest"
FROM empl
첫 번째 버전은 논리적이지만 두 번째 버전은 특별한 경우일 수도 있고 성능 최적화일 수도 있습니다.
MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno)
문은 (대략) 오른쪽에서 왼쪽 순서로 고려할 수 있습니다.
OVER (PARTITION BY deptno)
행을 구별되는 그룹으로 분할하는 것을 의미합니다.deptno
그 때에ORDER BY sal
평균, 각 파티션에 대해 행 순서 지정sal
(반드시 사용)ASC
종료 순서); 그러면KEEP (DENSE_RANK FIRST
각 파티션에 대해 순서가 지정된 행에 (연속적인) 순위를 부여하고(순서 열에 대한 값이 동일한 행에는 동일한 순위가 부여됨), 마지막으로 순위가 지정되지 않은 모든 행을 삭제합니다.MIN(sal)
각 파티션의 나머지 행에 대해 최소 급여를 반환합니다.
이 경우에는MIN
그리고.DENSE_RANK FIRST
둘 다 운영 중입니다.sal
칼럼 그래서 같은 일을 할 것이고 그리고.KEEP (DENSE_RANK FIRST ORDER BY sal)
중복됩니다.
그러나 최소값에 대해 다른 열을 사용하면 다음과 같은 효과를 볼 수 있습니다.
Oracle 11g R2 스키마 설정:
CREATE TABLE test (name, sal, deptno) AS
SELECT 'a', 1, 1 FROM DUAL
UNION ALL SELECT 'b', 1, 1 FROM DUAL
UNION ALL SELECT 'c', 1, 1 FROM DUAL
UNION ALL SELECT 'd', 2, 1 FROM DUAL
UNION ALL SELECT 'e', 3, 1 FROM DUAL
UNION ALL SELECT 'f', 3, 1 FROM DUAL
UNION ALL SELECT 'g', 4, 2 FROM DUAL
UNION ALL SELECT 'h', 4, 2 FROM DUAL
UNION ALL SELECT 'i', 5, 2 FROM DUAL
UNION ALL SELECT 'j', 5, 2 FROM DUAL;
쿼리 1:
SELECT DISTINCT
MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) AS min_sal_first_sal,
MAX(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) AS max_sal_first_sal,
MIN(name) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) AS min_name_first_sal,
MAX(name) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) AS max_name_first_sal,
MIN(name) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION BY deptno) AS min_name_last_sal,
MAX(name) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION BY deptno) AS max_name_last_sal,
deptno
FROM test
결과:
| MIN_SAL_FIRST_SAL | MAX_SAL_FIRST_SAL | MIN_NAME_FIRST_SAL | MAX_NAME_FIRST_SAL | MIN_NAME_LAST_SAL | MAX_NAME_LAST_SAL | DEPTNO |
|-------------------|-------------------|--------------------|--------------------|-------------------|-------------------|--------|
| 1 | 1 | a | c | e | f | 1 |
| 4 | 4 | g | h | i | j | 2 |
이 예제에서는 집계가 정렬하는 열과 동일한 열에 있기 때문에 차이가 없습니다."KEEP"의 실제 포인트/파워는 서로 다른 열을 집계하고 정렬할 때입니다.예를 들어, (다른 답변에서 "테스트" 표를 빌림)...
SELECT deptno, min(name) keep ( dense_rank first order by sal desc, name ) ,
max(sal)
FROM test
group by deptno
;
이 쿼리는 각 부서에서 가장 높은 급여를 받는 사람의 이름을 가져옵니다."KEEP" 조항이 없는 대안을 고려해 보십시오.
SELECT deptno, name, sal
FROM test t
WHERE not exists ( SELECT 'person with higher salary in same department'
FROM test t2
WHERE t2.deptno = t.deptno
and (( t2.sal > t.sal )
OR ( t2.sal = t.sal AND t2.name < t.name ) ) )
KEEP 절은 더 쉽고 효율적입니다(이 간단한 예에서는 3개의 일관된 get 대 34개의 get).
@MT0의 답변에 언급된 한 가지 차이점에 대해 자세히 설명합니다.첫 번째 쿼리에서는 집계 함수 MIN과 MAX가 작업을 수행하고 두 번째 쿼리에서는 실제 행이 FIRST, LAST 및 KEEP에 의해 선택됩니다.
두 번째 예제에서는 MAX를 MIN으로 대체할 수도 있으며 이는 여전히 정답(최고 연봉)을 제공합니다.
자세한 내용은 다음 문서를 참조하십시오.
두 개의 열을 기준으로 순서를 지정하고 두 열 중 하나를 가져오거나 둘 다 가져오는 경우에 유용할 수 있습니다.
CREATE TABLE test (name, sal, deptno) AS
SELECT 'adam', 100, 1 FROM DUAL
UNION ALL SELECT 'bravo', 500, 1 FROM DUAL
UNION ALL SELECT 'coy', 456, 1 FROM DUAL
UNION ALL SELECT 'david', 50, 1 FROM DUAL
UNION ALL SELECT 'ethan', 50, 1 FROM DUAL
UNION ALL SELECT 'feral', 300, 1 FROM DUAL;
이제 사람의 급여뿐만 아니라 급여가 가장 낮은 직원을 선택하려고 합니다.조건은 두 명의 직원이 동일한 최저 임금을 받는 경우 이름이 알파벳 순으로 첫 번째인 직원을 데려오는 것입니다.
select o.deptno
,min(o.sal) keep
(dense_rank first order by o.sal, o.name) least_salary
,min(o.name) keep
(dense_rank first order by o.sal, o.name) least_salary_person
from test o
group by
o.deptno;
출력:
DEPTNO LEAST_SALARY LEAST_SALARY_PERSON
1 50 david
이 쿼리는 각 부서에서 가장 높은 급여를 받는 사람의 이름을 가져옵니다.
select MIN(ename),sal,deptno
from emp where sal in
(
select max(sal) from emp group by deptno
)
GROUP BY sal,deptno;
언급URL : https://stackoverflow.com/questions/20145952/partition-by-with-and-without-keep-in-oracle
'programing' 카테고리의 다른 글
Python으로 이미지 표시 (0) | 2023.06.16 |
---|---|
iOS UIBarButtonItem의 제목 텍스트 제거 (0) | 2023.06.16 |
.NET 4.5로 업그레이드한 후 iFrame 파서 오류 발생 (0) | 2023.06.16 |
모양 및 데이터 유형으로 배열을 할당할 수 없습니다. (0) | 2023.06.16 |
R 세션에서 사용 가능한 메모리를 관리하는 방법 (0) | 2023.06.16 |