실험 빈로우가_선택되었을시에_대체방법
2011.05.03 23:27
스터디를 끝마치고, 남은 하루 일과 중 30분 남짓해서 올립니다.
SELECT * FROM EMP;
-- 빈로우가 선택되었을시에 대체방법
SELECT COUNT(EMPNO) AS CNT
FROM EMP
WHERE ENAME = 'SMITH'
AND JOB <> 'CLERK';
-- 안된다...
SELECT COUNT(EMPNO) AS CNT
FROM EMP
WHERE ENAME = 'SMITH'
AND JOB <> 'CLERK'
GROUP BY EMPNO;
-- 안된다...
SELECT NVL(COUNT(EMPNO), 0) AS CNT
FROM EMP
WHERE ENAME = 'SMITH'
AND JOB <> 'CLERK'
GROUP BY EMPNO;
-- 역시 안된다...
SELECT DECODE(COUNT(EMPNO), 0, 0, COUNT(EMPNO)) AS CNT
FROM EMP
WHERE ENAME = 'SMITH'
AND JOB <> 'CLERK'
GROUP BY EMPNO;
-- 좋다 GROUP BY 빼보자! 된다...!
SELECT DECODE(COUNT(EMPNO), 0, 0, COUNT(EMPNO)) AS CNT
FROM EMP
WHERE ENAME = 'SMITH'
AND JOB <> 'CLERK';
-- 역시 안된다...
SELECT DECODE(COUNT(EMPNO), 0, 'SALESMAN', MAX(JOB)) AS JOB
FROM EMP
WHERE ENAME = 'SMITH'
AND JOB <> 'CLERK'
GROUP BY JOB;
-- 이유가 뭘까.....!?
-- GROUP BY를 주었을때와 안주었을시에 왜 다를까...
SELECT DECODE(COUNT(EMPNO), 0, 'SALESMAN', MAX(JOB)) AS JOB
FROM EMP
WHERE ENAME = 'SMITH'
AND JOB <> 'CLERK';
댓글 2
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
8 | 문자열(CHAR과 VARCHAR에서 공백비교), CTAS 문에서 제약유지(mssql실험) | balto | 2012.03.23 | 42915 |
7 | 소트에 관한 자료 [2] | balto | 2011.06.15 | 40687 |
6 | A조 여러분! 어제 잠시 스터디에서 얘기했던 내용에 11g의 Nested Loop Join에 대한 정리가 되어있네요.. [1] | 멋진넘 | 2011.06.08 | 34179 |
5 | MERGE 문에서 DELETE CLAUSE에서 참조열 | darkbeom | 2011.05.09 | 43394 |
4 | 4월30일 세미나 자료 - 데이터모델링 표기법 [4] | suspace | 2011.05.04 | 46694 |
3 | 4월30일 세미나 자료 - Query Transformation [1] | 멋진넘 | 2011.05.03 | 41524 |
» | 빈로우가_선택되었을시에_대체방법 [2] | darkbeom | 2011.05.03 | 38274 |
1 | 통계정보 수집 관련 test [2] | 오라클잭 | 2011.03.23 | 52403 |
어제 범석씨 질문에 남팀장이 설명을 잘 했지만... 얘기를 계속하면 시간이 길어질까봐서
오늘 댓글로 사족을 조금 남겨 봅니다.
이미 테스트 하셨던 내용에 SELECT LIST를 조금 변형해서 진행해 보겠습니다.
SELECT COUNT(EMPNO) AS CNT, MAX(EMPNO) MAXEMP, 'CASE 1' VALUE
FROM EMP
WHERE ENAME = 'SMITH'
AND JOB <> 'CLERK'
UNION ALL
SELECT COUNT(EMPNO) AS CNT, MAX(EMPNO) MAXEMP, 'CASE 2' VALUE
FROM EMP
WHERE ENAME = 'SMITH'
AND JOB <> 'CLERK'
GROUP BY EMPNO
;
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 36 | 6 (34)| 00:00:01 |
| 1 | UNION-ALL | | | | | |
| 2 | SORT AGGREGATE | | 1 | 18 | | |
|* 3 | TABLE ACCESS FULL | EMP | 1 | 18 | 4 (0)| 00:00:01 |
| 4 | SORT GROUP BY NOSORT | | 1 | 18 | 2 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 18 | 2 (0)| 00:00:01 |
| 6 | INDEX FULL SCAN | PK_EMP | 14 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
<결과>
CNT | MAXEMP | VALUE
----|--------|-------
0 | | CASE 1
어제도 얘기했지만 차이점은 GROUP BY의 사용여부입니다.
우선 GRUOP BY를 빼면 우리가 일반적으로 사용하는 단순한 SQL 구문입니다.
다만 DBMS에서 데이타를 표현할 때 SELECT LIST에서 GROUP 함수를 쓰면 무조건 표현을 해야한다는
차이가 있습니다.
데이타가 존재하지 않더라도 COUNT의 경우는 0, MIN/MAX의 경우는 NULL형태로...(★★★)
하지만 두번째 SELECT 리스트에는 NO DATA에서 GROUP BY를 해야할 대상이 없기에
다른 무슨 짓을 해도 데이타는 표현이 안되겠지요..
조금 더 사족을 덧붙이면 다음과 같은 원리입니다.
CREAET TABLE YHN_TMP (A NUMBER);
SELECT COUNT(*), MAX(A), 'CASE1' CASE FROM YHN_TMP
UNION ALL
SELECT COUNT(*), MAX(A), 'CASE2' CASE FROM YHN_TMP
GROUP BY A
;
위 SQL처럼 빈 껍데기 테이블을 하나 만들고 COUNT(*)를 하면 당연히 0이 나오겠지만,
NO DATA인 상태에서 GROUP BY를 한다면 역시 DATA는 NO ROW SELECTED라고 표현이 되겠지요.
SELECT MAX(1) MAX_VAL, 'CASE1' CASE
FROM DUAL
WHERE 1 = 2
UNION ALL
SELECT 2 MAX_VAL, 'CASE2' CASE
FROM DUAL
WHERE 1 = 2
;
위 SQL도 같은 맥락이겠지요..(어제 다 얘기한 내용 복습입니다. ^^;;;)