반응형

 

1. INNER JOIN

 - JOIN 조건에 동일한 값이 있는 행만 반환

- INNER JOIN 표시는 그 동안 WHERE 절에서 사용하던 JOIN 조건을 FROM 절에서 정의하겠다는 표시

- USING 조건절이나 ON 조건절을 필수적으로 사용해야 함

 

2. NATURAL JOIN

 - 두 테이블 간의 동일한 이름을 갖는 모든 칼럼들에 대해 EQUI(=) JOIN을 수행

 - 추가로 USING 조건절, ON 조건절, WHERE 절에서 JOIN 조건을 정의할 수 없음

 - SQL Server에서 지원하지 않는 기능임

 - SELECT DEPTNO, EMPNO, ENAME, DNAME

   FROM EMP NATURAL JOIN DEPT;

 - 별도의 JOIN 컬럼을 지정하지 않았지만, 두 개의 테이블에서 DEPTNO라는 공통된 칼럼을 자동으로 인식하여 JOIN을 처리한 것임

 - JOIN에 사용된 컬럼들은 같은 데이터 유형이어야 하며, ALIAS나 테이블명과 같은 접두사를 붙일 수 없음 

 - NATURAL JOIN은 JOIN이 되는 테이블의 데이터 성격(도메인)과 칼럼명 등이 동일해야 하는 제약 조건이 있음

 - 간혹 모델링 상의 부주의로 인해 동일한 칼럼명이라도 다른 용도의 데이터를 저정하는 경우도 있으므로 주의 요망

 

3. USING 조건절

 - FROM 절의 USING 조건절을 이용하면 같은 이름을 가진 칼럼들 중에서 원하는 칼럼에 대해서만 선택적으로 EQUI JOIN을 할 수 있음

 - SQL Server에서 지원하지 않음

 - USING 조건절을 이용한 EQUI JOIN에서 JOIN 칼럼에 대해서 ALIAS나 테이블 이름과 같은 접두사를 붙일 수 없음(DEPT.DEPTNO ---> DEPTNO)

 - 잘못된 사례

 SELECT DEPT.DEPTNO, DEPT.DNAME, DEPT.LOC, DEPT_TEMP.DNAME, DEPT_TEMP.LOC

 FROM DEPT JOIN DEPT_TEMP

 USING (DEPTNO);

- 바른 사례 

 SELECT DEPTNO, DEPT.DNAME, DEPT.LOC, DEPT_TEMP.DNAME, DEPT_TEMP.LOC

 FROM DEPT JOIN DEPT_TEMP

 USING (DEPTNO);

 

 

4. ON 조건절

 - JOIN 서술부(ON 조건절)와 비JOIN 서술부(WHERE 조건절)를 분리하여 이해가 쉬우며, 칼럼명이 다르더라도 JOIN 조건을 사용할 수 있음

 - 이름이 다른 칼럼명을 JOIN 조건으로 사용하거나, JOIN 칼럼을 명시하기 위해서는 ON 조건절을 사용한다.

 - ON 조건절에 사용된 괄호는 옵션이다.

 - ON 조건절을 사용한 JOIN의 경우는 ALIAS나 테이블 명과 같은 접두사를 사용하여 SELECT에 사용되는 칼럼을 논리적으로 명확하게 지정해주어야 한다. (USING 조건절을 이용한 JOIN에서는 JOIN 칼럼에 대해서 ALIAS나 테이블명과 같은 접두사를 사용하면 SYNTAX 에러가 발생한다.)

 - FROM 절에 테이블이 많이 사용될 경우 다소 복잡하게 보여 가독성이 떨어질 수 있다.

 

 1) ON 조건절 예제 - 팀과 스타디움 테이블을 스타디움ID로 JOIN하여 팀이름, 스타디움ID, 스타디움 이름을 찾아본다.

SQL> SELECT TEAM_NAME, TAEM.STADIUM_ID, STADIUM_NAME

         FROM TEAM JOIN STADIUM

         ON TEAM.STADIUM_ID = STADIUM.STADIUM_ID

         ORDER BY STADIUM_ID;

 

STADIUM_ID라는 공통된 칼럼이 있기 때문에 아래처럼 USING 조건절로 구현할 수도 있다.

 

SQL> SELECT TEAM_NAME, STADIUM_ID, STADIUM_NAME

         FROM TEAM JOIN STADIUM

         USING (STADIUM_ID)

         ORDER BY STADIUM_ID;

 

INNNER JOIN으로 구현할 수도 있다.

 

SQL> TEAM_NAME, TEAM.STADIUM_ID, STADIUM_NAME

         FROM TEAM, STADIUM

         WHERE TEAM.STADIUM_ID = STADIUM.STADIUM_ID

         ORDER BY STADIUM_ID;

 

 

 2) 팀과 스타디움 테이블을 팀ID로 JOIN하여 팀이름, 팀ID, 스타디움 이름을 찾아본다. STADIUM에는 팀ID가 HOMETEAM_ID라는 칼럼으로 표시되어 있다.

 

 SQL> SELECT TEAM_NAME, TEAM_ID, STADIUM_NAME

          FROM TEAM JOIN STADIUM

          ON TEAM.TEAM_ID = STADIUM.HOMETEAM_ID

          ORDER BY TEAM_ID;

 

 WHERE절의 INNER JOIN으로 구현 가능

 

 SQL> SELECT TEAM_NAME, TEAM_ID, STADIUM_NAME

          FROM TEAM, STADIUM

          WHERE TEAM.TEAM_ID = STADIUM.HOMETEAM_ID

          ORDER BY TEAM_ID;

 

 3) 다중 테이블 JOIN

 - 사원과 DEPT 테이블의 소속 부서명, DEPT_TEMP 테이블의 바뀐 부서명 정보를 출력한다.

 SQL> SELECT E.EMPNO, D.DEPTNO, D.DNAME, T.DNAME New_DNAME

          FROM EMP E JOIN DEPT D

          ON (E.DEPTNO = D.DEPTNO)

                JOIN DEPT_TEMP T

          ON (E.DEPTNO = T.DEPTNO);

 

WHERE절의 INNNER JOIN으로 구현 가능

 

 SQL> SELECT E.EMPNO, D.DEPTNO, D.DNAME, T.DNAME New_DNAME

          FROM EMP E, DEPT D, DEPT_TEMP T

          WHERE E.DEPTNO = D.DEPTNO

          AND E.DEPTNO = T.DEPTNO; 

 

 - GK 포지션의 선수별 연고지명, 팀명, 구장명을 출력


SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션, T.REGION_NAME 연고지명,
       T.TEAM_NAME 팀명, S.STADIUM_NAME 구장명
FROM PLAYER P JOIN TEAM T
ON P.TEAM_ID = T.TEAM_ID
   JOIN STADIUM S
ON T.STADIUM_ID = S.STADIUM_ID
WHERE P.POSITION = 'GK'
ORDER BY 선수명;


WHERE절의 INNNER JOIN으로 구현 가능


SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션, T.REGION_NAME 연고지명,
       T.TEAM_NAME 팀명, S.STADIUM_NAME 구장명
FROM PLAYER P, TEAM T, STADIUM S
WHERE P.TEAM_ID = T.TEAM_ID
AND T.STADIUM_ID = S.STADIUM_ID
AND P.POSITION = 'GK'
ORDER BY 선수명;

 

 

 - 홈팀이 3점 이상 차이로 승리한 경기의 경기장 이름, 경기 일정, 홈팀 이름과 원정팀 이름 정보를 출력


SELECT ST.STADIUM_NAME, SC.STADIUM_ID, SCHE_DATE, SCHE_DATE, HT.TEAM_NAME,
       AT.TEAM_NAME, HOME_SCORE, AWAY_SCORE
FROM SCHEDULE SC JOIN STADIUM ST
ON SC.STADIUM_ID = ST.STADIUM_ID
   JOIN TEAM HT
ON SC.HOMETEAM_ID = HT.TEAM_ID
   JOIN TEAM AT
ON SC.AWAYTEAM_ID = AT.TEAM_ID
WHERE HOME_SCORE >= AWAY_SCORE + 3;


WHERE절의 INNNER JOIN으로 구현 가능


SELECT ST.STADIUM_NAME, SC.STADIUM_ID, SCHE_DATE, SCHE_DATE, HT.TEAM_NAME,
       AT.TEAM_NAME, HOME_SCORE, AWAY_SCORE
FROM SCHEDULE SC, STADIUM ST, TEAM HT, TEAM AT
WHERE HOME_SCORE >= AWAY_SCORE + 3
AND SC.STADIUM_ID = ST.STADIUM_ID
AND SC.HOMETEAM_ID = HT.TEAM_ID
AND SC.AWAYTEAM_ID = AT.TEAM_ID;

 

 

5. OUTER JOIN

 1)LEFT OUTER JOIN
 - 테이블 A와 B가 있을 때(Table 'A'가 기준이 됨), A와 B를 비교해서 B의 JOIN 칼럼에서 같은 값이 있을 때 그 해당 데이터를 가져오고, B의 JOIN 칼럼에서
같은 값이 없는 경우에는 B 테이블에서 가져오는 칼럼들은 NULL 값으로 채운다.
 - OUTER 키워드 생략 가능
 
 - SELECT STADIUM_NAME, STADIUM.STADIUM_ID, SEAT_COUNT, HOMETEAM_ID, TEAM_NAME
   FROM STADIUM LEFT OUTER JOIN TEAM
   ON STADIUM.HOMETEAM_ID = TEAM.TEAM_ID
   ORDER BY HOMETEAM_ID;

 OUTER는 생략 가능한 키워드 임.

 - SELECT STADIUM_NAME, STADIUM.STADIUM_ID, SEAT_COUNT, HOMETEAM_ID, TEAM_NAME
   FROM STADIUM LEFT JOIN TEAM
   ON STADIUM.HOMETEAM_ID = TEAM.TEAM_ID
   ORDER BY HOMETEAM_ID;


 2)RIGHT OUTER JOIN
 - LEFT OUTER JOIN과 반대로 생각(A의 JOIN 칼럼에서 같은 값이 없는 경우에는 A 테이블에서 가져오는 칼럼들은 NULL 값으로 채운다.)
 - OUTER 키워드 생략 가능

 - SELECT E.ENAME, D.DEPTNO, D.DNAME, D.LOC
   FROM EMP E RIGHT OUTER JOIN DEPT D
   ON E.DEPTNO = D.DEPTNO;

 OUTER는 생략 가능한 키워드 임.

 - SELECT E.ENAME, D.DEPTNO, D.DNAME, D.LOC
   FROM EMP E RIGHT JOIN DEPT D
   ON E.DEPTNO = D.DEPTNO;

 


 3)FULL OUTER JOIN

 - RIGHT OUTER JOIN과 LEFT OUTER JOIN의 결과 합집함
 - 단, UNION ALL이 아닌 UNION 기능과 같으므로 중복되는 데이터는 삭제
 - OUTER 키워드 생략 가능

 - DEPTNO 기준으로 DEPT와 DEPT_TEMP 데이터를 FULL OUTER JOIN으로 출력한다.
 
   SELECT *
   FROM DEPT FULL OUTER JOIN DEPT_TEMP
   ON DEPT.DEPTNO = DEPT_TEMP.DEPTNO;

   OUTER는 생략 가능한 키워드 임.

   SELECT *
   FROM DEPT FULL JOIN DEPT_TEMP
   ON DEPT.DEPTNO = DEPT_TEMP.DEPTNO;


   아래와 같이 표현이 가능함.

   SELECT L.DEPTNO, L.DNAME, L.LOC, R.DEPTNO, R.DNAME, R.LOC
   FROM DEPT L LEFT OUTER JOIN DEPT_TEMP R
   ON L.DEPTNO = R.DEPTNO
   UNION
   SELECT L.DEPTNO, L.DNAME, L.LOC, R.DEPTNO, R.DNAME, R.LOC
   FROM DEPT L RIGHT OUTER JOIN DEPT_TEMP R
   ON L.DEPTNO = R.DEPTNO;

 


 

 

 

 

 

반응형
반응형

 

예제) 사원 테이블에서 급여가 높은 3명만 내림차순으로 출력

 

1.     잘못된 예 – Oracle의 경우 정렬이 완료된 후 데이터의 일부가 출력되는 것이 아니라, 데이터의 일부가 먼저 추출된 후(ORDER BY 절은 결과 집합을 결정하는데 관여하지 않음) 데이터에 대한 정렬 작업이 일어나므로 주의해야 한다.

 

      SELECT ENAME, SAL

      FROM EMP

      WHERE ROWNUM < 4

      ORDER BY SAL DESC;

 

2.     성공적인 예 – ORDER BY 절이 사용되는 경우 ORACLE ROWNUM 조건을 ORDER BY 절보다 먼저 처리되는 WHERE 절에서 처리하므로, 정렬 후 원하는 데이터를 얻기 위해서는 인라인 뷰에서 먼저 데이터 정렬을 수행한 후 메인쿼리에서 ROWNUM 조건을 사용해야 한다.

 

SELECT ENAME, SAL

FROM (SELECT ENAME, SAL

FROM EMP

ORDER BY SAL DESC)

WHERE ROWNUM < 4;

 

반응형
반응형

 

SQL전문가 가이드 p. 274

SELECT 문장 실행 순서 옵티마이저가 SQL 문장의 SYNTAX, SEMANTIC 에러를 점검하는 순서

 

5. SELECT 컬럼명 [ALIAS]

1. FROM 테이블명

2. WHERE 조건식

3. GROUP BY 칼럼(Column)이나 표현식

4. HAVING 그룹조건식

6. ORDER BY 칼럼(Column)이나 표현식;

 

1. 발췌 대상 테이블을 참조한다. (FROM)

2. 발췌 대상 데이터가 아닌 것을 제거한다. (WHERE)

3. 행들을 소그룹화 한다. (GROUP BY)

4. 그룹핑된 값의 조건에 맞는 것만을 출력한다. (HAVING)

5. 데이터 값을 출력/계산한다. (SELECT)

6. 데이터를 정렬한다. (ORDER BY)

 

반응형
반응형

p. 270

*ORDER BY 절 사용 특징

- 기본적인 정렬 순서는 오름차순(ASC)이다.

- 숫자형 데이터 타입은 오름차순으로 정렬했을 경우에 가장 작은 값부터 출력된다.

- 날짜형 데이터 타입은 오름차순으로 정렬했을 경우 날짜 값이 가장 빠른 값이 먼저 출력된다. 예를 들어 ’01-JAN-2012’’01-SEP-2012’보다 먼저 출력된다.

- Oracle에서는 NULL 값을 가장 큰 값으로 간주하여 오름차순으로 정렬했을 경우에는 가장 마지막에, 내림차순으로 정렬했을 경우에는 가장 먼저 위치한다.

- 반면, SQL Server에서는 NULL 값을 가장 작은 값으로 간주하여 오름차순으로 정렬했을 경우에는 가장 먼저, 내림차순으로 정렬했을 경우에는 가장 마지막에 위치한다.

- GROUP BY 절에서 그룹핑 기준을 정의하게 되면 데이터베이스는 일반적인 SELECT 문장처럼 FROM절에 정의된 테이블의 구조를 그대로 가지고 가는 것이 아니라, GROUP BY 절의 그룹핑 기준에 사용된 컬럼과 집계 함수에 사용될 수 있는 숫자형 데이터 칼럼들의 집합을 새로 만든다. (p.276)

- GROUP BY 이후에 수행 절인 SELECT절이나 ORDER BY 절에서 개별 데이터를 사용하는 경우 에러가 발생한다. (p.276)

- 결과적으로 SELECT 절에서는 그룹핑 기준과 숫자 형식 칼럼의 집계 함수를 사용할 수 있지만, 그룹핑 기준 외의 문자 형식 칼럼은 정할 수 없다. (p.276)

 

예제) 칼럼 순서번호 + ALIAS명 사용 ORDER BY 절 사용

SELECT DNAME, LOC AREA, DEPTNO

FROM DEPT

ORDER BY 1, AREA, 3 DESC;

 

반응형
반응형

 

p. 265 – 집계 함수와 NULL 처리

 

CASE 표현 사용시 ELSE 절을 생략하게 되면 Default 값이 NULL이다. NULL은 연산의 대상이 아닌 반면, SUM(CASE MONTH WHEN 1 THEN SAL ELSE 0 END) 처럼 ELSE 절에서 0(Zero)을 지정하면 불필요하게 0 SUM 연산에 사용되므로 자원의 사용이 많아진다. 같은 결과를 얻을 수 있다면 가능한 ELSE 절의 상수값을 지정하지 않거나 ELSE 절을 작성하지 않도록 한다. 같은 이유로 Oracle DECODE 함수는 4번째 인자를 지정하지 않으면 NULL Default로 할당된다.

 

많이 실수하는 것 중에 하나가 Oracle SUM(NVL(SAL,0)), SQL Server SUM(ISNULL(SAL,0)) 연산이다. 개별 데이터의 급여(SAL) NULL인 경우는 NULL의 특성으로 자동적으로 SUM 연산에서 빠지는 데, 불필요하게 NVL/ISNULL 함수를 사용해 0(Zero)으로 변환시켜 데이터 건수만큼의 연산이 일어나게 하는 것은 시스템의 자원을 낭비하는 일이다.

 

리포트 출력 때 NULL이 아닌 0을 표시하고 싶은 경우에는 NVL(SUM(SAL),0)이나, ISNULL(SUM(SAL),0) 처럼 전체 SUM의 결과가 NULL인 경우(대상 건수가 모두 NULL인 경우)에만 한 번 NVL/ISNULL 함수를 사용하면 된다.

 

예제) 팀별 포지션별 FW, MF, DF, GK 포지션의 인원수와 팀별 전체 인원수를 구하는 SQL 문장을 작성한다. 데이터가 없는 경우는 0으로 표시한다.

 

*SIMPLE_CASE_EXPRESSION 조건

 

SELECT TEAM_ID,

         NVL(SUM(CASE POSITION WHEN ‘FW’ THEN 1 ELSE 0 END), 0) FW,

NVL(SUM(CASE POSITION WHEN ‘MF’ THEN 1 ELSE 0 END), 0) MF,

NVL(SUM(CASE POSITION WHEN ‘DF’ THEN 1 ELSE 0 END), 0) DF,

NVL(SUM(CASE POSITION WHEN ‘GK’ THEN 1 ELSE 0 END), 0) GK,

COUNT(*) SUM

FROM PLAYER

GROUP BY TEAM_ID;

 

*SIMPLE_CASE_EXPRESSION 조건

-       CASE 표현의 ELSE 0, ELSE NULL 문구는 생략 가능하므로 다음과 같이 조금 더 짧게 SQL 문장을 작성할 수 있다. Default 값인 NULL이 적용됨.

 

SELECT TEAM_ID,

         NVL(SUM(CASE POSITION WHEN ‘FW’ THEN 1 END), 0) FW,

NVL(SUM(CASE POSITION WHEN ‘MF’ THEN 1 END), 0) MF,

NVL(SUM(CASE POSITION WHEN ‘DF’ THEN 1 END), 0) DF,

NVL(SUM(CASE POSITION WHEN ‘GK’ THEN 1 END), 0) GK,

COUNT(*) SUM

FROM PLAYER

GROUP BY TEAM_ID;

 

 

*SEARCHED _CASE_EXPRESSION 조건

 

SELECT TEAM_ID,

         NVL(SUM(CASE WHEN POSITION = ‘FW’ THEN 1 END), 0) FW,

NVL(SUM(CASE WHEN POSITION = ‘MF’ THEN 1 END), 0) MF,

NVL(SUM(CASE WHEN POSITION = ‘DF’ THEN 1 END), 0) DF,

NVL(SUM(CASE WHEN POSITION = ‘GK’ THEN 1 END), 0) GK,

COUNT(*) SUM

FROM PLAYER

GROUP BY TEAM_ID;

 

 

예제) GROUP BY 절 없이 전체 선수들의 포지션별 평균 키 및 평균 키를 출력할 수도 있다.

SELECT ROUND(AVG(CASE WHEN POSITION = ‘MF’ THEN HEIGHT END), 2) 미드필더,

ROUND(AVG(CASE WHEN POSITION = ‘FW’ THEN HEIGHT END), 2) 포워드,

ROUND(AVG(CASE WHEN POSITION = ‘DF’ THEN HEIGHT END), 2) 디펜더,

ROUND(AVG(CASE WHEN POSITION = ‘GK’ THEN HEIGHT END), 2) 골키퍼,

ROUND(AVG(HEIGHT),2) 전체평균키

FROM PLAYER;

반응형
반응형

p. 264 – CASE 표현과 Oracle DECODE 함수의 차이점 비교

SELECT DEPTNO,

         AVG(CASE MONTH WHEN 1 THEN SAL END) M01,

         AVG(CASE MONTH WHEN 2 THEN SAL END) M02,

AVG(CASE MONTH WHEN 3 THEN SAL END) M03,

AVG(CASE MONTH WHEN 4 THEN SAL END) M04,

AVG(CASE MONTH WHEN 5 THEN SAL END) M05,

AVG(CASE MONTH WHEN 6 THEN SAL END) M06,

AVG(CASE MONTH WHEN 7 THEN SAL END) M07,

AVG(CASE MONTH WHEN 8 THEN SAL END) M08,

AVG(CASE MONTH WHEN 9 THEN SAL END) M09,

AVG(CASE MONTH WHEN 10 THEN SAL END) M10,

AVG(CASE MONTH WHEN 11 THEN SAL END) M11,

AVG(CASE MONTH WHEN 12 THEN SAL END) M12

FROM (SELECT ENAME, DEPTNO, EXTRACT(MONTH FROM HIREDATE) MONTH, SAL

       FROM EMP)

GROUP BY DEPTNO;

 

SELECT DEPTNO,

         AVG(DECODE(MONTH, 1, SAL)) M01, AVG(DECODE(MONTH, 2, SAL)) M02,

AVG(DECODE(MONTH, 3, SAL)) M03, AVG(DECODE(MONTH, 4, SAL)) M04,

AVG(DECODE(MONTH, 5, SAL)) M05, AVG(DECODE(MONTH, 6, SAL)) M06,

AVG(DECODE(MONTH, 7, SAL)) M07, AVG(DECODE(MONTH, 8, SAL)) M08,

AVG(DECODE(MONTH, 9, SAL)) M09, AVG(DECODE(MONTH, 10, SAL)) M10,

AVG(DECODE(MONTH, 11, SAL)) M11, AVG(DECODE(MONTH, 12, SAL)) M12

FROM (SELECT ENAME, DEPTNO, EXTRACT(MONTH FROM HIREDATE) MONTH, SAL

       FROM EMP)

GROUP BY DEPTNO;

 

반응형
반응형

p. 255

*여려 행들의 그룹이 모여서 그룹당 단 하나의 결과를 돌려주는 다중행 함수 중 집계 함수(aggregate function)의 특성

- 여려 행들의 그룹이 모여서 그룹당 단 하나의 결과를 돌려주는 함수

- GROUP BY 절은 행들을 소그룹화함

- SELECT, HAVING, ORDER BY 절에 사용 가능

 

p.256

*GROUP BY절과 HAVING절의 특성

- GROUP BY 절을 통해 소그룹별 기준을 정한 후, SELECT 절에 집계 함수를 사용한다.

- 집계 함수의 통계 정보는 NULL 값을 가진 행을 제외하고 수행한다.

- GROUP BY 절에서는 SELECT 절과는 달리 ALIAS 명을 사용할 수 없다.

- 집계 함수는 WHERE 절에는 올 수 없다.

- WHERE 절은 전체 데이터를 GROUP으로 나누기 전에 행들을 미리 제거시킨다.

- HAVING 절은 GROUP BY 절의 기준 항목이나 소그룹의 집계 함수를 이용한 조건을 표시할 수 있다.

- GROUP BY 절에 의한 소그룹별로 만들어진 집계 데이터 중, HAVING 절에서 제한 조건을 두어 조건을 만족하는 내용만 출력한다.

- HAVING 절은 일반적으로 GROUP BY 절 뒤에 위치한다.

- WHERE 절은 FROM 절에 정의된 집합(주로 테이블)의 개별 행에 WHERE 절의 조건절이 먼저 적용되고, WHERE 절의 조건에 맞는 행이 GROUP BY 절의 대상이 된다.

- WHERE 절의 조건 변경은 대상 데이터의 개수가 변경되므로 결과 데이터 값이 변경될 수 있지만, HAVING 절의 조건 변경은 결과 데이터 변경은 없고 출력되는 레코드의 개수만 변경될 수 있다.

 

반응형
반응형

p. 245

*NVL(oracle)/ISNULL(mssql) 함수의 특성

- 널 값은 아직 정의되지 않은 값으로 0 또는 공백과 다르다. 0은 숫자이고, 공백은 하나의 문자이다.

- 테이블을 생성할 때 NOT NULL 또는 PRIMARY KEY로 정의되지 않은 모든 데이터 유형은 널 값을 포함할 수 있다.

- 널 값을 포함하는 연산의 경우 결과 값도 널 값이다.

- 결과값을 NULL이 아닌 다른 값을 얻고자 할 때 NVL(oracle)/ISNULL(mssql) 함수를 사용한다. NULL 값의 대상이 숫자 유형 데이터인 경우는 주로 0(Zero)으로, 문자 유형 데이터인 경우는 블랭크보다는 ‘x’ 같이 해당 시스템에서 의미 없는 문자로 바꾸는 경우가 많다.

- NVL 함수를 다중행 함수의 인자로 사용하는 경우는 오히려 불필요한 부하를 발생할 수 있으므로 굳이 NVL 함수를 사용할 필요가 없다. 다중행 함수는 입력 값으로 전체 건수가 NULL 값인 경우만 함수의 결과가 NULL이 나오고 전체 건수 중에서 일부만 NULL인 경우는 다중행 함수의 대상에서 제외한다.(예를 들면 100명 중 10명의 성적이 NULL 값일 때 평균을 구하는 다중행 함수 AVG를 사용하면 NULL값이 아닌 90명의 성적에 대해서 평균값을 구하게 된다.)

 

예제) 급여와 커미션을 포함한 연봉을 계산하면서 NVL 함수의 필요성을 알아 본다.

SELECT ENAME 사원명, SAL 월급, COMM 커미션, (SAL*12) + COMM 연봉A, (SAL*12) + NVL(COMM, 0) 연봉B FROM EMP;

 

 

p. 246

*단일행 NULL 관련 함수의 종류

일반형 함수

함수 설명

NVL(표현식1, 표현식2) /

ISNULL(표현식1, 표현식2)

표현식1의 결과값이 NULL이면 표현식2의 값을 출력한다. , 표현식1과 표현식2의 결과 데이터 타입이 같아야 한다.

NULL 관련 가장 많이 사용되는 함수이므로 상당히 중요하다.

NULLIF(표현식1, 표현식2)

표현식1이 표현식2와 같으면 NULL, 같지 않으면 표현식1을 리턴한다.

COALESCE(표현식1, 표현식2, …)

임의의 개수 표현식에서 NULL이 아닌 최초의 표현식을 나타낸다. 모든 표현식이 NULL이라면 NULL을 리턴한다.

 

 p. 250

*NULL과 공집합

SELECT 1 FROM DUAL WHERE 1 = 2; 와 같은 조건이 대표적인 공집합을 발생시키는 쿼리이며, 위와 같이 조건에 맞는 데이터가 한 건도 없는 경우를 공집합이라고 하고, NULL 데이터와는 또 다르게 이해해야 한다.

 

 p. 252

*NULLIF

EXPR1 EXPR2와 같으면 NULL, 같지 않으면 EXPR1을 리턴한다. 특정 값을 NULL로 대체할 경우에 유용하게 사용할 수 있다.

예제) 사원 테이블에서 MGR 7698이 같으면 NULL, 같지 않으면 MGR을 표시한다.

 

반응형
반응형

 

p. 242

 

*단일행 CASE 표현의 종류

 

CASE 표현

함수 설명

CASE

 SIMPLE_CASE_EXPRESSION 조건

 ELSE 표현절

END

SIMPLE_CASE_EXPRESSION 조건이 맞으면 SIMPLE_CASE_EXPRESSION 조건내의 THEN 절을 수행하고, 조건이 맞지 않으면 ELSE 절을 수행한다.

CASE

 SEARCHED_CASE_EXPRESSION 조건

 ELSE 표현절

END

SEARCHED_CASE_EXPRESSION 조건이 맞으면 SEARCHED_CASE_EXPRESSION 조건내의 THEN 절을 수행하고, 조건이 맞지 않으면 ELSE 절을 수행한다.

DECODE(표현식, 기준값1, 1 [, 기준값2, 2, … , 디폴트값])

Oracle에서만 사용되는 함수로, 표현식의 값이 기준값1이면 값1을 출력하고, 기준값2이면 값2를 출력한다. CASE 표현의 SIMPLE_CASE_EXPRESSION 조건과 동일하다.

 

*CASE 표현은 함수의 성질을 가지고 있으므로, 다른 함수처럼 중첩해서 사용할 수 있다.

예제) 사원 정보에서 급여가 2000 이상이면 보너스를 1000으로, 1000 이상이면 500으로, 1000 미만이면 0으로 계산한다.

 

SELECT ENAME, SAL,

       CASE WHEN SAL >= 2000

            THEN 1000

       ELSE ( CASE WHEN SAL >= 1000

                   THEN 500

                   ELSE 0

             END)

       END as BONUS

FROM EMP;

 

예제) 부서 정보에서의 부서 위치를 미국의 동부, 중부, 서부로 구분하라.

SELECT LOC,

 CASE LOC

 WHEN ‘NEW YORK’ THEN ‘EAST’

 WHEN ‘BOSTON’ THEN ‘EAST’

 WHEN ‘CHICAGO’ THEN ‘CENTER’

 WHEN ‘DALLAS’ THEN ‘CENTER’

 ELSE ‘ETC’

 END as AREA

FROM DEPT;

 

예제) 사원 정보에서 급여가 3000 이상이면 상등급, 1000 이상이면 중등급으로, 1000 미만이면 하등급으로 분류하라.

SELECT ENAME,

       CASE WHEN SAL >= 3000 THEN ‘HIGH’

            WHEN SAL >= 1000 THEN ‘MID’

            ELSE ‘LOW’

       END AS SALARY_GRADE

FROM EMP;

 

반응형
반응형



확인 결과 v$recovery_file_dest의 사이즈가 100G에 도달해서 DB가 down되는 문제였습니다.

1. DB 복구
C:\> sqlplus sys/test as sysdba
SQL> recover database until cancel;
SQL> alter database open resetlogs;

2. 파일 삭제(D드라이브의 backup 폴더로 이동)



3. RMAN으로 CROSSCHECK와 DELETE EXPIRED 수행
C:\> sqlplus sys/test as sysdba
SQL> alter database begin backup;
SQL> alter database end backup;
SQL> alter system checkpoint;
SQL> alter system switch logfiile;
SQL> host

C:\> rman target sys/test

RMAN> crosscheck archivelog all;
RMAN> delete expired archivelog all; [yes]

4. 사이즈 확인

SQL> select name, floor(space_limit/1024/1024) "Size MB", ceil(space_used/1024/1024) "Used MB" from v$recovery_file_dest order by name;



-------------------------------------------------------------------------------------------------

recovery dest 는

최종 온라인 백업 된 이후의 로그들을 지울수 있습니다.


db에 접속하셔서
alter database begin backup
alter database end backup 찍으시고,
alter system checkpoint 찍으시고,
이후에, alter system switch logfiile 하신후에

rman target /nolog 로 접속 하시고,
crosscheck archive og all;
delete expired archivelog all; [yes]


-------------------------------------------------------------------------------------------------

http://majesty76.tistory.com/54


 

 

 

 

 

 

 

 

 


 

반응형