검색결과 리스트
글
--단순CASE식--
CASE sex
WHEN '1' THEN '남'
WHEN '2' THEN '여'
ELSE '기타'
END
--검색CASE식--
CASE WHEN sex = '1' THEN '남'
WHEN sex = '2' THEN '여'
ELSE '기타' END
CASE식의 서식은 위와 같이 단순CASE식과 검색CASE식 두가지가 있다. 단순 CASE식은 이름 그대로 간결하게 쓸 수 있으나 비교조건 밖에 가능하지 못한 반면 검색 CASE식은 다양한 비교조건을 사용할 수 있다.
1.기존 코드체계를 새로운 체계로 변경하여 집계하기
PopTbl 집계결과
pref_name
population
지방명
인구
인천
100
경기
650
수원
200
→
경북
600
광명
150
기타
450
안양
200
대구
300
경주
100
포항
200
부산
400
제주
50
왼쪽 테이블의 도시별 인구를 집계하는 SQL을 만들어보자.
SELECT CASEpref_name
DISTRICT SUM(POPULATION) |
2.다른 조건의 집계를 하나의 SQL로 행하기
pref_name |
sex |
population |
지방명 |
남 |
여 | |
인천 |
1 |
60 |
인천 |
60 |
40 | |
인천 |
2 |
40 |
수원 |
100 |
100 | |
수원 |
1 |
100 |
광명 |
100 |
50 | |
수원 |
2 |
100 |
|
안양 |
100 |
100 |
광명 |
1 |
100 |
→ |
대구 |
100 |
200 |
광명 |
2 |
50 |
경주 |
20 |
80 | |
안양 |
1 |
100 |
포항 |
125 |
125 | |
안양 |
2 |
100 |
서울 |
250 |
150 | |
대구 |
1 |
100 |
||||
대구 |
2 |
200 |
||||
경주 |
1 |
20 |
||||
경주 |
2 |
80 |
||||
포항 |
1 |
125 |
||||
포항 |
2 |
125 |
||||
서울 |
1 |
250 |
||||
서울 |
2 |
150 |
|
SELECT pref_name,
PREF_NAME CNT_M CNT_F
|
3. 조건을 분지시킨 UPDATE
name |
salary |
영희 |
300000 |
순희 |
270000 |
민희 |
220000 |
원희 |
290000 |
위의 테이블에 대해, 다음과 같은 조건으로 변경시켜보자
1.현재의 급료가 30만이상인 사원은 10%삭감한다.
2.현재의 급료가 25만이상 28미만인 사원은 20%인상한다.
단순히 생각하면 다음과 같이 UPDATE문을 2번 실행하면 될 것 같지만 이는 맞지 않다.
--조건1. |
왜 이런 결과가 나올까? 예를 들어 현재 급료가 30만원인 사원의 경우 조건1의 UPDATE문에 의해 급료가 27만원으로 줄었다. 하지만 이것이 끝이 아니라 다음에 실행되는 조건2의 UPDATE문에 의해서 32만4000원으로 늘어나버리기 때문이다. 두가지 조건을 정확하게 반영하는 SQL문은 다음과 같다.
UPDATE Personnel |
위의 SQL뮨은 정확한데다 한번의 실행으로 해결되기 때문에 속도도 빨라진다.
4. 테이블 간의 매칭
DECODE함수등과 비료해서 CASE식의 최대 장점은 식을 평가가능하다는 것이다. 이말은 즉, CASE식 중에 BETWEEN,LIKE,<,>등을 사용할 수 있다는 말이다. 그 중에서도 IN 과EXISTS는 서브쿼리를 인수로 취하기 때문에 매우 강력한 표현력을 가진다.
CourseMaster OpenCourses
course_id |
course_name |
month |
course_id | |
1 |
피아노 |
200706 |
1 | |
2 |
태권도 |
200706 |
3 | |
3 |
미술 |
200706 |
4 | |
4 |
컴퓨터 |
200707 |
4 | |
200708 |
2 | |||
200708 |
4 | |||
위 테이블로 부터 다음과 같은 월별 개강 상태를 한눈에 알 수 있도록 표를 만들어보자.
COURSE_NAME 6월 7월 8월 |
이는 즉, OpenCourses의 어느 달에 CourseMaster테이블의 강좌가 존재하는지를 체크하는 것이다. 이 매칭의 조건을 CASE식으로 쓰는 것이 가능하다.
--IN 이용-- SELECT CM.course_name, --EXISTS 이용-- SELECT CM.course_name, |
IN 이나EXISTS 어느쪽을 써도 결과는 같지만 퍼포먼스면에서 EXISTS를 쓰는 편이 좋다. 서브쿼리에서 (month, course_id)라는 주키의 인덱스를 이용할 수 있기 때문에 특히나 OpenCourses테이블의 사이즈가 클 경우는 굉장히 우위에 서게 된다.
5.CASE식 중에 집약함수를 사용
std_id |
club_id |
club_name |
main_club_flg |
100 |
1 |
야구 |
Y |
100 |
2 |
기타 |
N |
200 |
2 |
기타 |
N |
200 |
3 |
배드민턴 |
Y |
200 |
4 |
축구 |
N |
300 |
4 |
축구 |
N |
400 |
5 |
수영 |
N |
500 |
6 |
바둑 |
N |
학생은 복수의 클럽에 소속되어있는 경우도 있으면 (100,200), 1개밖에 소속되지 않은 경우도 있다.(300,400,500). 복수의 클럽에 소속되어 있는 학생에 대해서는 주클럽이 어느것인지 나타내는 클럽열에 Y 혹은 N 의 값이 들어간다. 1개의 클럽에만 전념하는 학생은 N이 들어간다.
그럼, 위 테이블로부터 다음과 같은 조건으로 쿼리를 만든다.
1. 1개의 클럽에 소속된 학생에 대해서는 그 클럽의 ID를 취득한다.
2. 복수의 클럽에 소속된 학생에 대해서는 주요한 클럽의 ID를 취득한다.
단순히 생각하면 다음과 같은 두개의 조건에 대응하는 쿼리를 만들면 될 것이다.
--조건1 :1개의 클럽에 전념하는 학생을 선택-- select std_id, max(club_id) main_club
--조건2 : 복수 클럽에 소속되어 있는 학생을 선택-- select std_id, club_id main_club
|
이것으로도 조건에 만족하는 결과를 얻을 수 있지만 열에 의해 복수의 SQL이 필요하다. CASE식을 쓰면, 다음과 같은 한개의 SQL만으로 쓸 수 있다.
select std_id, STD_ID MAIN_CLUB |
CASE식 중에 집약함수를 써서, 거기다 그 안에 CASE식을 쓰는 어지러워보이는 네스트구조이지만 정리하자면 「한개 클럽에 전념하는가, 복수의 클럽에 소속되어 있는가」라는 조건분지를 CASE WHEN COUNT(*) _ 1 .....ELSE .....라는 CASE식으로 표현한 것이다. 이는 혁명적인 표현방법이다. 왜냐하면 우리가 처음 SQL입문을 배울 때 집계결과에 대한 조건은 HAVING구를 써서 설정한다고 배웠지만 CASE식을 쓰면 SELECT구에서도 동등 조건 분지를 쓸 수 있기 때문이다. 이 예문에서도 알 수 있듯이 CASE식은 SELECT구에서 집약함수 중에서도 밖에서도 쓸 수 있다. 이 자유도가 높은 점이 CASE식의 큰 매력이다.
------ 정리
SQL에서의 cASE식을 순차적언어의 CASE문에 연연해서 CASE「문」이라고 하는 경우가 있다. 하지만 정확히는 문이 아니라 1+1이나 a/b와 같은 식의 동료이다. 「문」과「식」의 차이는 기능의 방식의 차이를 반영하는 중요한 포이트이다. 식이기 때문에 CASE식은 실행시에는 평가되어져 하나의 값으로 결정되어지고 (그렇기 때문에 집약함수 중에 쓸 수 있다), 식이기 때문에 SELECT구에서도 GROUP BY구에서도 WHERE구에서도 ORDER BY구에서도 쓸 수 있는 것이다. 쉽게 말하면 CASE식은 열명이나 정수를 쓸 수 있는 장소에서는 언제든지 쓸 수 있다.
[출처] SQL _ CASE식|작성자 미우
'먹고살기 > Oracle' 카테고리의 다른 글
SQL _ 상관서브쿼리 (0) | 2011.04.29 |
---|---|
SQL _ HAVING_2 (0) | 2011.04.29 |
[Oracle] ROWNUM 사용 시 주의 (0) | 2011.04.25 |
오라클 데이터 타입 (0) | 2011.04.22 |
오라클 DECODE (0) | 2011.04.22 |
RECENT COMMENT