[SQL] 와 BY와 오라클의 KEEP없이 PARTITION
SQL와 BY와 오라클의 KEEP없이 PARTITION
파티션에 집계 함수를 적용 : 나는 같은 결과를 갖고있는 것 같아요 두 개의 질의를 가로 질러왔다.
이 두 개의 쿼리 사이에 어떤 차이가 있는지 궁금 오전 :
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
첫 번째 버전은 더 논리적이다하지만, 두 번째는 어떤 특별한 경우에, 어쩌면 약간의 성능을 최적화 할 수있다.
해결법
-
==============================
1.당신의 집계는 당신이 정렬되는 것과 같은 열 때문에 당신의 예에서 차이가 없습니다. 당신이 다른 열에 종류의 집계 때 'KEEP'의 진정한 포인트 / 전원입니다. 예를 들어 (다른 답변에서 "테스트"테이블을 차입) ...
당신의 집계는 당신이 정렬되는 것과 같은 열 때문에 당신의 예에서 차이가 없습니다. 당신이 다른 열에 종류의 집계 때 '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 ) ) )
킵 절보다 쉽고 효율적이다 ((34)는이 간단한 예에서 대안을 얻는다 대 단 3 일치 가져).
-
==============================
2.
MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno)
명령문은 (대략) 오른쪽에서 왼쪽 순서로 고려 될 수있다 :
이 경우 MIN 및 DENSE_RANK FIRST는 SAL 컬럼에 모두 운영 그렇게 같은 일을하고 KEEP (DENSE_RANK FIRST ORDER BY의 샐를) 할 것입니다 중복입니다.
당신은 최소 다른 열을 사용하지만 경우에 당신은 효과를 볼 수 있습니다
SQL 바이올린
오라클 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 |
-
==============================
3.MT0의 대답 @에서 언급 한 차이를 자세히 설명합니다 : 첫 번째 쿼리에서 집계 함수 MIN과 MAX는 일을하고있다 제 중에 실제 행은 FIRST, LAST 및 KEEP 의해 촬상되고있다.
MT0의 대답 @에서 언급 한 차이를 자세히 설명합니다 : 첫 번째 쿼리에서 집계 함수 MIN과 MAX는 일을하고있다 제 중에 실제 행은 FIRST, LAST 및 KEEP 의해 촬상되고있다.
당신은 두 번째 예에서는 MIN과 MAX를 대체 할 수 있으며 여전히 정답 (가장 높은 급여를) 제공합니다.
더 많은 정보를 위해 다음 문서를 참조하십시오.
-
==============================
4.두 열의으로 주문 및 중 하나 또는 둘 모두 그 열을 가져 오는 경우 그것은 또한 도움이 될 수 있습니다.
두 열의으로 주문 및 중 하나 또는 둘 모두 그 열을 가져 오는 경우 그것은 또한 도움이 될 수 있습니다.
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;
이제 두 직원이 같은 최저 임금이있는 경우 이름이 첫 번째 알파벳 오는 하나를 가져되어 가장 낮은 급여와 직원뿐만 아니라 person.Condition의 급여를 선택합니다.
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
-
==============================
5.이 쿼리는 각 부서에서 가장 높은 급여를 가진 사람의 이름을 가져옵니다.
이 쿼리는 각 부서에서 가장 높은 급여를 가진 사람의 이름을 가져옵니다.
select MIN(ename),sal,deptno from emp where sal in ( select max(sal) from emp group by deptno ) GROUP BY sal,deptno;
from https://stackoverflow.com/questions/20145952/partition-by-with-and-without-keep-in-oracle by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL - INSERT 및 ID 자동 증가 값을 잡기 (0) | 2020.07.03 |
---|---|
[SQL] 어떻게 내가 준비된 문을 사용하지 않고 SQL을 소독 (0) | 2020.07.03 |
[SQL] 여러 테이블이 많은 관계로 하나가 필요합니다 (0) | 2020.07.03 |
[SQL] MySQL의 또는 일반적으로 SQL에서 BETWEEN과 IN 사이의 성능 차이가 있나요? (0) | 2020.07.03 |
[SQL] SQL Server의 일광 절약 시간 시작 및 종료 기능을 만드는 방법 (0) | 2020.07.03 |