예를 들어, 'JOB'이 'SALESMAN'이면 'COMM'기준으로 정렬하고, 그렇지 않으면 'SAL'을 기준으로 정렬하고자 한다. 반환하려는 결과셋을 확인하고 해법을 생각해본다.
ORDER BY
절에서 CASE
를 사용한다CASE WHEN THEN END
구문은 정말 함수처럼 작동한다. 아마 다른 내장 함수들도 그렇게 작동할 것 같다. SELECT
절에서 열을 추가하는 방법으로 사용했는데, 여기서는 `ORDER BY절에서도 사용하고 있음을 설명해주고 있다.
/* ORACLE */
select ename, sal, job, comm
from emp
order by case when job='salesman' then comm
else sal
end;
>>
ENAME SAL JOB COMM
SMITH 800 CLERK -
JAMES 950 CLERK -
ADAMS 1100 CLERK -
MARTIN 1250 SALESMAN 1400
WARD 1250 SALESMAN 500
MILLER 1300 CLERK -
TURNER 1500 SALESMAN 0
ALLEN 1600 SALESMAN 300
CLARK 2450 MANAGER -
BLAKE 2850 MANAGER -
JONES 2975 MANAGER -
FORD 3000 ANALYST -
SCOTT 3000 ANALYST -
KING 5000 PRESIDENT -
그런데 Oracle과 Maria에서의 결과가 다르게 나온다...
/* Maria */
select ename, sal, job, comm
from emp
order by case when job='salesman' then comm
else sal
end;
>>
+--------+------+-----------+------+
| ename | sal | job | comm |
+--------+------+-----------+------+
| TURNER | 1500 | SALESMAN | 0 |
| ALLEN | 1600 | SALESMAN | 300 |
| WARD | 1250 | SALESMAN | 500 |
| SMITH | 800 | CLERK | NULL |
| JAMES | 950 | CLERK | 0 |
| ADAMS | 1100 | CLERK | NULL |
| MILLER | 1300 | CLERK | NULL |
| MARTIN | 1250 | SALESMAN | 1400 |
| CLARK | 2450 | MANAGER | NULL |
| BLAKE | 2850 | MANAGER | NULL |
| JONES | 2975 | MANAGER | NULL |
| SCOTT | 3000 | ANALYST | NULL |
| FORD | 3000 | ANALYST | NULL |
| KING | 5000 | PRESIDENT | NULL |
| IREN | 9000 | TESTER | 9000 |
+--------+------+-----------+------+
일단 책에서 나온 결과셋은 Maria와 일치한다.
Oracle에서 왜 다른 결과가 나오는지는 알 수 없다.
Oracle Live를 쓰고 있기 때문에, 지난 세션에서 뭔가를 잘못 건드린 것 같기도 하다.
이 부분은 시간이 넉넉할 때 다시 확인해보기로 하겠다.
책의 결과셋과 일치한 Maria로 다음을 진행해본다.
CASE
식을 사용하여 결과의 정렬 방식을 동적으로 변경할 수 있다 / ORDER BY
에 전달된 값을 다음 쿼리에서 확인하라/* 동적 정렬 */
select ename, sal, job, comm,
# 아래의 CASE구문에서 다섯 번째 칼럼을 동적으로 생성하고
case when job='salesman' then comm
else sal end as ordered
from emp
# 아래의 ORDER BY절에서 다섯 번째 칼럼을 기준으로 했다
order by 5
매우 참신한 풀이다!
쿼리 결과의 정렬은 SQL의 핵심기술 중 하나이다. ORDER BY
절은 매우 강력하지만 해법에서의 미묘한 차이를 이해해야 한다.
SELECT
구문에 CASE WHEN THEN END
구문을 사용하여 보조 열을 하나 생성하여 정렬했다SELECT
절에 붙어있으므로 조회하려는 열이 좀 더 명확해지는 느낌을 받았다CASE WEHN THEN END
구문의 반환값 사용ORDER BY
구문에 CASE WHEN THEN END
구문을 사용하여 정렬한 방법이 전형적인 것 같기도 하다아직 어떤 방법이 어떤 경우에 더 유리한지는 잘 모르겠다. 동적 정렬은 SELECT
절이 조금 길어지면서 ORDER BY
절로 열의 인덱스까지 정해줘야 하는 단점이 있는 것 같다.
ORDER BY
절이 해법에서 미묘한 차이를 보이며, 이를 이해해야 한다고 나와 있는데 아직은 정말 잘 모르겠다 ㅠㅠ
공부가 많이 필요하다.