반응형

 

Character set 이 맞지 않아 한글이 깨져 ?로 표시 된다 당혹감을 감출 수 없음..

Character Set은 각 나라는 영의 ASCII영역 뒤에 추가적인 바이트를 추가하는 방식으로 사용 한다고 한다

주로 한글은 2Byte, UTF8은 3Byte를 가진다고 한다

그러므로, 같은 ASCII문자로 구성하더라도 다른 값을 가르키거나 없기 때문에 ?가 나오는 것이다.

 

먼저 NLS_CHARACTERSET 을 확인 해보았다

 

select * from nls_database_parameters where parameter ='NLS_CHARACTERSET';

 

 

이제 sysdba로 들어가 아래와 같이수행해준다.

SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL> ALTER DATABASE OPEN;
SQL> ALTER DATABASE CHARACTER SET KO16MSWIN949;

 

alter database character set ko16mswin949
*
ERROR at line 1:
ORA-12712: new character set must be a superset of old character set

==> 잘 수행하다 이런 에러가 뜬다.

      찾아보니 새로운 캐릭터 셋은 반드시 기존 캐릭터 셋이여야만 한다고 한다.

      무슨 말인고 하니 아래 표를 참조하면 알 수 있다.

      (자세한 내용 : http://cafe.naver.com/mudong.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=548)

기존 캐릭터 셋 

새로운 캐릭터 셋 

변경 가능 여부 

 US7ASCII

 KO16KSC5601/KO16MSWIN949/UTF8/AL32UTF8

 가능

 KO16KSC5601

 KO16MSWIN949

 가능

 KO16MSWIN949

 UTF8

 불가능

 UTF8

 AL32UTF8

 가능

 

SQL> ALTER DATABASE CHARACTER SET INTERNAL_USE KO16MSWIN949;


SQL> SHUTDOWN IMMEDIATE
SQL> STARTUP
SQL> SELECT * FROM nls_database_parameters where parameter = 'NLS_CHARACTERSET';

 

 

다시 조회 해보자

 

?????????????????????????????????????????????????????????????????????

한글로 됐다..............

 

캐릭터셋이 변경되면서 유실됐나보다 다시 데이터를 넣고 조회해보니

 

 

깔끔하게 나왔다!

 

 

'Study Note > Database' 카테고리의 다른 글

DDL  (0) 2016.02.04
DML  (0) 2016.02.04
SUB QUERY (서브쿼리)  (0) 2016.02.04
JOIN  (0) 2016.02.04
집합 연산자  (0) 2016.02.04
반응형

SUB QUERY(서브쿼리)

 

 

 기본 문법

 SELECT SELECT_LIST

FROM TABLE 또는 VIEW

WHERE 조건 연산자 (SELECT SELECT_LIST

FROM TABLE

WHERE 조건);

 유형

 

SELECT ENAME, SAL

FROM EMP

WHERE SAL>(SELECT SAL

FROM EMP

WHERE ENAME='SCOTT');

 

 

■ 단일행 서브쿼리

--단일행 SUB QUERY 연습문제1

--STUDENT 테이블과 DEPARTMENT 테이블을 사용하여 이윤나 학생과 1전공(DEPTNO1)이 동일한 학생들의 이름과

--1전공 이름을 출력하세요

 

SELECT S.NAME, D.DNAME

FROM STUDENT S, DEPARTMENT D

WHERE S.DEPTNO1 = (SELECT DEPTNO1

FROM STUDENT

WHERE NAME = '이윤나')

AND S.DEPTNO1 = D.DEPTNO;

 

 

--단일행 SUB QUERY 연습문제2

--PROFESSOR 테이블에서 입사일이 송도권 교수보다 나중에 입사한 사람의 이름과 입사일, 학과명을 출력하세요

 

SELECT P.NAME, P.HIREDATE, D.DNAME

FROM PROFESSOR P, DEPARTMENT D

WHERE HIREDATE > (SELECT HIREDATE

FROM PROFESSOR

WHERE NAME = '송도권')

AND P.DEPTNO = D.DEPTNO;

 

--단일행 SUB QUERY 연습문제3

--STUDENT 테이블에서 1전공(DEPTNO1)101번 인 학과의 평균 몸무게보다 몸무게가 많은 학생들의 이름과 몸무게를

--출력하세요.

 

SELECT NAME,WEIGHT

FROM STUDENT

WHERE WEIGHT > (SELECT AVG(WEIGHT)

FROM STUDENT

WHERE DEPTNO1 = 101);

 

--단일행 SUB QUERY 연습문제4

--PROFESSOR 테이블에서 심슨 교수와 같은 입사일에 입사한 교수 중에서 조인형 교수보다 월급을 적게 받는 교수의

--이름과 급여, 입사일을 출력하세요

 

SELECT NAME,PAY,HIREDATE

FROM PROFESSOR

WHERE PAY < (SELECT PAY

FROM PROFESSOR

WHERE NAME = '조인형')

AND HIREDATE = (SELECT HIREDATE

FROM PROFESSOR

WHERE NAME = '심슨');

 

■  다중 행 SUB QUERY 

SUB QUERY의 결과과 2건 이상 출력되는 것을 말한다. 다중 행 SUB QUERYSUB QUERY의 결과가 여러건 출력되기 때문에 단일 행 연산자를 사용할 수 없다. 그래서 다중 행 SUB QUERY의 경우 아래와 같이 별도의 연산자가 존재함

 

연산자

의미

IN

같은 값을 찾음

>ANY

최소 값을 반환함

<ANY

최대 값을 반환함

<ALL

최소 값을 반환함

>ALL

최대 값을 반환함

EXISTS

SUB QUERY의 값이 있을 경우 반환함

 

SAL > ANY (100,200,300) 으로 되면 ANY 자리에 최소값인 100이 반환

SAL > 100이라는 식으로 표현

 

SAL < ALL (100,200,300) 이 되면 SUB QUERY의 최소 값인 100이 반환되긴 하지만 식은

SAL < 100이 되 버림

 

 

--EMP 테이블의 부서 별로 가장 급여를 많이 받는 사원의 사원번호 , 이름, 급여 , 부서번호를 조회하여라

 

SELECT EMPNO,ENAME,SAL,DEPTNO

FROM EMP

WHERE SAL IN (SELECT MAX(SAL)

FROM EMP

GROUP BY DEPTNO);

 

--다중 행 SUB QUERY

--EMP2 테이블과 DEPT2 테이블을 참조하여 근무지역(DEPT2 테이블의 AREA 컬럼)이 서울 지사인 모든 사원들의

--사번과 이름, 부서번호를 출력

 

SELECT EMPNO, NAME, DEPTNO

FROM EMP2

WHERE DEPTNO IN (SELECT DCODE

FROM DEPT2

WHERE AREA = '서울지사');

 

-- 업무가 SALESMAN 인 최소 한 명 이상의 사원보다 급여를 많이 받는 사원의 이름, 업무를 조회하여라

 

SELECT ENAME, JOB, SAL

FROM EMP

WHERE SAL > ANY( SELECT SAL

FROM EMP

WHERE JOB = 'SALESMAN')

AND JOB !='SALESMAN';

 

-- 다중 행 SUB QUERY 2

-- EMP2 테이블을 사용하여 전체 직원 중 과장 직급의 최소 연봉자보다 연봉이 높은 사람의 이름과 직급,

-- 연봉을 출력하세요. 단 연봉 출력 형식은 아래와 같이 천 단위 구분기호와 원 표시를 하세요

 

SELECT NAME, POSITION, PAY

FROM EMP2

WHERE 1=1

AND POSITION != '과장'

AND PAY > ANY(SELECT PAY

FROM EMP2

WHERE POSITION = '과장');

 

 

-- 다중 행 SUB QUERY 3

-- STUDENT 테이블을 조회하여 전체 학생 중에서 체중이 4학년 학생들의 체중이 4학년 학생들의 체중에서 가장 적게

-- 나가는 학생보다 몸무게가 적은 학생의 이름과 학년과 몸무게를 출력하세요.

 

SELECT NAME, GRADE, WEIGHT

FROM STUDENT

WHERE WEIGHT < ALL(SELECT WEIGHT

FROM STUDENT

WHERE GRADE =4)

 

   

■  다중 컬럼 SUB QUERY

서브쿼리로 출력되는 컬럼수가 2개 이상 출력되는 서브 쿼리

 

SELECT EMPNO, ENAME, SAL, DEPTNO

FROM EMP

WHERE (DEPTNO,SAL) IN (SELECT DEPTNO, MAX(SAL)

FROM EMP

GROUP BY DEPTNO);

 

-- 다중 컬럼 SUB QUERY 1

-- STUDENT 테이블을 조회하여 각 학년별로 최대키를 가진 학생들의 학년과 이름과 키를 출력하세요

 

SELECT GRADE,NAME,HEIGHT

FROM STUDENT

WHERE (GRADE,HEIGHT) IN (SELECT GRADE,MAX(HEIGHT)

FROM STUDENT

GROUP BY GRADE)

ORDER BY 1;

 

-- 다중 컬럼sub query 연습문제 1:

-- PROFESSOR 테이블을 조회하여 각 학과 별로 입사일이 가장 오래된 교수의 교수번호와 이름, 학과명을 출력하세요

-- (학과이름순으로 오름차순 정렬)

 

SELECT P.NAME, D.DNAME

FROM PROFESSOR P , DEPARTMENT D

WHERE (P.DEPTNO,P.HIREDATE) IN ( SELECT DEPTNO,MIN(HIREDATE)

FROM PROFESSOR

GROUP BY DEPTNO )

AND P.DEPTNO = D.DEPTNO

ORDER BY D.DNAME ;

 

 

-- 다중 컬럼 SUB QUERY 연습문제 2

-- EMP2 테이블을 조회하여 직급별로 해당 직급에서 최대 연봉을 받는 직원의 이름이 직급, 연봉을 출력하세요

-- 연봉순으로 오름차순 정렬하세요

 

SELECT NAME, PAY

FROM EMP2

WHERE (POSITION,PAY) IN ( SELECT POSITION,MAX(PAY)

FROM EMP2

GROUP BY POSITION)

ORDER BY PAY;

 

-- 다중 컬럼 SUB QUERY 연습문제 3 -- 다중행 컬럼 서브쿼리

-- EMP2 테이블을 조회하여 각 부서별 평균 연봉을 구하고 그 중에서 평균 연봉이 가장 적은 부서의

-- 평균 연봉보다 적게 받는 직원들의 부서명, 직원명, 연봉을 출력하세요.

-- ( , 연봉이 적은 순으로 나열하세요)

 

SELECT D.DNAME,E.NAME,E.PAY

FROM EMP2 E, DEPT2 D

WHERE PAY < ALL (SELECT AVG(PAY)

FROM EMP2

GROUP BY DEPTNO)

AND D.DCODE = E.DEPTNO

ORDER BY PAY;

 

 

--STUDENT 테이블을 이용하여 사용자 아이디가 BINGO인 학생과 같은 학년인 학생의

--학번, 이름, 학년을 출력하여라

 

SELECT STUDNO, NAME, GRADE

FROM STUDENT

WHERE GRADE = (SELECT GRADE

FROM STUDENT

WHERE ID = 'bingo');

 

 

 

--STUDENT 테이블을 이용하여 101번 학과 학생들의 평균 몸무게보다 적은 학생의 이름, 학과번호,몸무게를 출력하여라.

 

SELECT NAME, DEPTNO1, WEIGHT

FROM STUDENT

WHERE WEIGHT < ( SELECT AVG(WEIGHT)

FROM STUDENT

WHERE DEPTNO1 = 101 );

 

 

 

--STUDENT,DEPARTMENT 테이블을 이용하여 정보(PART:100)에 소속된 모든 학생의 학번, 이름, 학과번호를 출력하여라

 

SELECT STUDNO, NAME, DEPTNO1

FROM STUDENT

WHERE DEPTNO1 IN (SELECT DEPTNO

FROM DEPARTMENT

WHERE PART = 100);

 

 

--STUDENT 테이블을 이용하여 모든 학생 중에서 4학년 학생 중 키가 제일 작은 학생보다 키가 큰 학생의

--학번, 이름, 키를 출력하여라

 

SELECT STUDNO, NAME, HEIGHT

FROM STUDENT

WHERE HEIGHT > ANY( SELECT HEIGHT

FROM STUDENT

WHERE GRADE = 4);

 

-- STUDENT 테이블을 이용하여 학년별로 몸무게가 최소인 학생의 이름, 학년, 몸무게를 출력하여라

 

SELECT NAME, GRADE, WEIGHT

FROM STUDENT

WHERE (GRADE,WEIGHT) IN (SELECT GRADE,MIN(WEIGHT)

FROM STUDENT

GROUP BY GRADE);

 

 

■  상호 연관 SUB QUERY 

- 메인쿼리절과 서브쿼리간에 검색 결과를 교환하는 서브쿼리

- 메인쿼리와 서브쿼리간의 결과를 교환하기 위하여 서브쿼리의 WHERE 조건절에서 메인쿼리의 테이블과 연결

*주의*

   행을 비교할 때마다 결과를 메인으로 반환하는 관계로 처리 성능이 저하될 수 있음

 

--상호 연관 SUB QUERY

-- EMP2 테이블을 조회해서 직원 들 중에서 자신의 직급의 평균연봉과 같거나 많이 받는 사람들의

--이름과 직급, 현재 연봉을 출력하세요

 

SELECT NAME, POSITION, PAY

FROM EMP2 A

WHERE PAY >= (SELECT AVG(PAY)

FROM EMP2 B

GROUP BY A.POSITION = B.POSITION);

 

 스칼라서브쿼리 : SELECT절에서 함수처럼 사용되는 쿼리문

- 하나의 레코드만 리턴이 가능( 반환값은 한 개) 두 개이상의 레코드는 리턴 X

- 일치하는 데이터가 없더라고 NULL 값을 리턴 할 수 있다.

 

SELECT D.DEPTNO, (SELECT MIN(EMPNO) FROM EMP WHERE DEPTNO = D.DEPTNO)

FROM DEPT D

ORDER BY D.DEPTNO;

 

 인라인뷰(상호연관 SUB QUERY 보다 성능이 좋음)

- FROM 절에서 임시 공간에 테이블을 생성하여 사용하는 뷰와 비슷한 저장 형태

- FROM 절에 있는 서브쿼리가 인라인 뷰를 생성

- 효율적인 검색 가능

- FROM 절에 있는 서브쿼리에는 자주 별칭 사용

 

--STUDENT 테이블을 이용하여 각 학년 별로 평균키보다 큰 학생들의 이름, 학년, 키를 출력하여라

 

SELECT NAME, A.GRADE, HEIGHT

FROM STUDENT A, (SELECT GRADE,AVG(HEIGHT) AS "B_HEIGHT"

FROM STUDENT

GROUP BY GRADE) B

WHERE A.HEIGHT > B_HEIGHT

AND A.GRADE = B.GRADE

ORDER BY GRADE,HEIGHT;

 

 

 

 

'Study Note > Database' 카테고리의 다른 글

DML  (0) 2016.02.04
[Tool] Orange Character Set 설정하기  (0) 2016.02.04
JOIN  (0) 2016.02.04
집합 연산자  (0) 2016.02.04
SQL 함수  (0) 2016.02.03
반응형

JOIN

■ Cartesian Product(카티션 곱)

Join 쿼리 중에 WHERE 절에 기술하는 Join 조건이 잘못 기술 되었거나 아예 없을 경우 발생

ex) select e.first_name, d.department_name

        from employees e, departments d;

* employees : 107  , departments : 27 개의 row가 있다면 (107x27)개의 결과를 출력하게 됨

 

 EQUI Join

양쪽 테이블에 같은 조건의 값이 존재할 경우 해당 데이터를 가져오는 JOIN 방법

Equal 연산자(=)를 사용해서 EQUI Join 이라고 함

 

select e.first_name , d.department_name
from employees e, departments d
where e.department_id = d.department_id
  and e.department_id = 110;

 

 

* 두 테이블을  JOIN 하여 dpartment_id가 110 인 row만 출력하게 함

 

--EQUI JOIN

-- 학생 테이블(STUDENT) 과 학과테이블(DEPARTMENT) 테이블을 사용하여 학생이름, 1전공학과번호(DEPTNO1),

-- 1전공 학과 이름을 출력하세요

 

SELECT * FROM STUDENT;

SELECT * FROM DEPARTMENT; 

 

SELECT S.NAME,S.DEPTNO1,D.DNAME

FROM STUDENT S,DEPARTMENT D

WHERE S.DEPTNO1=D.DEPTNO;

 

--EQUI JOIN2

--학생 테이블(STUDENT)과 교수테이블(PROFESSOR)JOIN 하여 학생의 이름과

--지도교수번호, 지도교수 이름을 출력

DESC STUDENT;

DESC PROFESSOR;

 

SELECT S.NAME,P.PROFNO,P.NAME

FROM STUDENT S,PROFESSOR P

WHERE S.PROFNO = P.PROFNO;

 

--EQUI JOIN 문제2) 학생테이블(STUDENT)과 교수 테이블(PROFESSOR)JOIN 하여 학생의 이름과 지도교수번호, 지도교수 이름을 출력하세요

 

SELECT S.NAME AS "학생이름",S.PROFNO AS "교수번호",P.NAME AS "교수이름"

FROM STUDENT S,PROFESSOR P

WHERE S.PROFNO = P.PROFNO;

 

--EQUI JOIN 문제3) 학생테이블(STUDENT)과 학과 테이블(DEPARTMENT), 교수 테이블(PROFESSOR)JOIN하여

-- 학생의 이름과 학과이름, 지도교수 이름을 출력하세요.

 

SELECT S.NAME AS "학생이름",D.DNAME AS "학과이름",P.NAME AS "교수이름"

FROM STUDENT S,DEPARTMENT D,PROFESSOR P

WHERE S.PROFNO = P.PROFNO

AND S.DEPTNO1 = D.DEPTNO ;

 

--EQUI JOIN 문제4) EMP2 테이블과 P_GRADE 테이블을 조회하여 사원의 이름과 직급, 현재 연봉, 해당 직급의 연봉의

-- 하한금액과 상한 금액을 출력하세요

 

SELECT E.NAME AS "사원이름", E.POSITION AS "현재직급",

E.PAY AS "현재연봉" ,P.S_PAY AS "하한금액", P.E_PAY AS "상한금액"

FROM EMP2 E,P_GRADE P

WHERE E.POSITION=P.POSITION;

 

--EQUI JOIN 문제5) 1전공(DEPTNO1)101번인 학생들의 학생 이름과 지도교수 이름을 출력하세요.

 

SELECT S.NAME,P.NAME

FROM STUDENT S, PROFESSOR P

WHERE S.PROFNO = P.PROFNO

AND S.DEPTNO1 = P.DEPTNO;

 

 NON EQUI Join

두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하지 않는 경우에 사용 ( “=” 연산자가아닌 다른 연산자들을 이용하여 JOIN )

EX)

SELECT GO.GNAME , GO.POINT, G.GNAME

FROM GOGAK GO,GIFT G

WHERE GO.POINT BETWEEN G.G_START AND G.G_END;

 

-- NON EQUI JOIN) STUDENT 테이블과 EXAM_01 테이블 , HAKJUM 테이블을 조회하여

-- 학생들의 이름과 점수와 배점을 출력하시오

 

SELECT S.NAME, E.TOTAL , H.GRADE

FROM STUDENT S, EXAM_01 E, HAKJUM H

WHERE S.STUDNO = E.STUDNO

AND E.TOTAL BETWEEN H.MIN_POINT AND H.MAX_POINT;

 

-- NON EQUI JOIN) GOGAK 테이블과 GIFT 테이블을 JOIN하여 고객이 자기 포인트보다 낮은 포인트의

-- 상품 중 한가지를 선택할 수 있다고 할 때 산악용 자전거를 선택할 수 있는

-- 고객명과 포인트, 상품명을 출력하세요

 

SELECT GO.GNAME,GO.POINT,GI.GNAME

FROM GOGAK GO, GIFT GI

WHERE GO.POINT >= GI.G_START AND GI.GNAME ='산악용자전거';

 

-- NON EQUI JOIN) EMP2테이블과 P_GRADE 테이블을 조회하여 사용자들의 이름과 나이 현재 직급, 예상 직급을

-- 출력하세요. 예상 직급은 나이로 계산하여 해당 나이가 받아야 하는 직급을 의미합니다.

-- 나이는 오늘(SYSDATE)를 기준으로 하되 TRUNC로 소수점 이하는 절삭해서 계산하시오

 

SELECT E.NAME "이름", TRUNC((SYSDATE-E.BIRTHDAY)/365) "현재나이",

E.POSITION "현재직급",

G.POSITION "예상직급"

FROM EMP2 E,P_GRADE G

WHERE TRUNC((SYSDATE-E.BIRTHDAY)/365) BETWEEN G.S_AGE AND G.E_AGE;

 

 OUTER Join

Join에 참가하는 여러 테이블에서 한쪽 테이블에는 데이터가 있고 한쪽 테이블에 없는 경우에

데이터가 있는 쪽 테이블의 내용을 전부 출력하게 하는 방법

 

OUTER JOIN 예제)  STUDENT 테이블과 PROFESSOR테이블을 JOIN 하여 학생이름과 지도교수 이름을 출력하시오

-- 단 지도학생이 결정되지 않은 교수의 명단도 함께 출력하세요

 

SELECT S.NAME, P.NAME

FROM STUDENT S, PROFESSOR P

WHERE S.PROFNO(+)=P.PROFNO;

 

--OUTER JOIN 예제 3) STUDENT 테이블과 PROFESSOR 테이블을 JOIN 하여 학생이름과 지도교수를 출력하시오

1)

SELECT S.NAME, P.NAME

FROM STUDENT S, PROFESSOR P

WHERE S.PROFNO=P.PROFNO(+)

UNION

SELECT S.NAME, P.NAME

FROM STUDENT S, PROFESSOR P

WHERE S.PROFNO(+)=P.PROFNO;

2)

SELECT S.NAME,P.NAME

FROM STUDENT S FULL OUTER JOIN PROFESSOR P

ON S.PROFNO = P.PROFNO;

 

■ SELF Join (재귀 조인)

원하는 데이터들이 하나의 테이블에 들어있을 때 사용

 

SELECT A.DNAME "부서명" , B.DNAME "상위부서명"

FROM DEPT2 A, DEPT2 B

WHERE A.PDEPT = B.DCODE;

 

-- SELF JOIN 연습문제 ) PROFESSOR 테이블에서 교수의 번호, 교수이름, 입사일, 자신보다 입사일 빠른사람 인원수를 출력

-- , 자신보다 입사일이 빠른 사람수를 오름차순으로 출력하시오.

 

SELECT A.PROFNO "교수의 번호", A.NAME "교수이름", A.HIREDATE "입사일", COUNT(B.NAME) "빠른사람"//*로 하면 널 값까지

FROM PROFESSOR A, PROFESSOR B

WHERE A.HIREDATE > B.HIREDATE(+)

GROUP BY A.PROFNO, A.NAME, A.HIREDATE

ORDER BY 빠른사람;

'Study Note > Database' 카테고리의 다른 글

[Tool] Orange Character Set 설정하기  (0) 2016.02.04
SUB QUERY (서브쿼리)  (0) 2016.02.04
집합 연산자  (0) 2016.02.04
SQL 함수  (0) 2016.02.03
SQL 기본 [ SELECT ]  (0) 2016.02.03

+ Recent posts