SQL

SQL 정리

음그냥 2024. 3. 8. 14:16
728x90
반응형
SMALL

<정리>

** EXISTS은 절안의 값이 사실여부인지만 체크하기때문에 
EXISTS 절안의 SELECT 컬럼이름은 SELECT 1이나 SELECT X 가 와도 상관없음

 

** 오라클에서 FROM절의 테이블나열은 조인을 의미함

 

** 조인은 여러방법으로 할수있음

 

1. FROM 테이블1,테이블2

WHERE 테이블1.컬럼1 = 테이블2.컬럼2

 

2. FROM 테이블1 JOIN 테이블2 ON 테이블1.컬럼1 = 테이블2.컬럼2

 

3. FROM 테이블 A

WHERE A.컬럼1 = (SELECT B.컬럼1 FROM 테이블B WHERE )

 

4. FROM 테이블 A

WHERE A IN (연관서브쿼리)

 

4. FROM 테이블 A

WHERE A EXIST (연관서브쿼리)

 

 

** 단일행은 =,>=, <=, <> 으로 가능

** 다중행은 IN, EXIST, NOT IN 등으로 가능

** 다중행 서브쿼리 비교연산자는 단일 행 서브쿼리의 비교연산자로도 사용할수있음

 

** 서브쿼리는 SELECT절, FROM 절, HAVING 절, ORDER BY절 등에서 사용가능

** 서브쿼리는 단일행 또는 복수행 비교연산자와 함께 사용할수있음

** 다중컬럼 서브쿼리는 서브쿼리의 결과로 여러개의 컬럼이 반환되어 메인쿼리의 조건과
동시에 비교되는것을 의미하고, 오라클에서만 사용가능

 

 

** using 오라클가능
using ( = ) 문법오류

 

** 오라클에서 +표시는 아웃터조인할때 씀
+붙인쪽의 반대쪽테이블이 기준이됨
+붙은 구문이 ansi구문으로 바꿀때 on절에 오면됨

 

 

 

** UNION ALL은 여러절의 문장있으면 첫번째 문장의 알리아스만 적용됨
** UNION ALL 후 UNION 하면 중복데이터 제거 (DISTINCT와 같음)

 

** 계층형구조

루트노드의 레벨값은 1임
이전레벨의 자식=부모가 와야 계층구조표현할수있음
순방향전개란 부모노드로부터 자식노드방향을 전개하는것을 말함
PRIOR 자식 = 부모 (순방향)  -> PRIOR 부서번호 = 상위부서번호
PRIOR 부모 = 자식 (역방향)  -> PRIOR 상위부서번호 = 부서번호

 

** BETWEEN 3 AND 5  => 3이상부터 5이하까지임

 

 

** 다중컬럼 서브쿼리는 오라클에서 지원, SQL SERVER에서는 지원안함
예) 
SELECT A
FROM EMP_94 TAB1
WHERE (A,B) IN ( SELECT D,F
                       FROM DEPT_94 TAB2 
                       WHERE TAB1.A = TAB2.F )

 

 

** COUNT(0) 은 0의 갯수임
** COUNT(NULL)은 없음

 

** GROUP BY 에서는 알리아스 못씀

 

** GROUP BY 없어도 HAVING 절 쓸수있음

 

** 서브쿼리는 항상 메인쿼리에서 읽혀진 데이터에 대해 서브쿼리에서 해당조건이 만족하는지를 확인하는 방식으로 수행된다 (X)=> 상황에 따라 다름

 

예) SELECT TAB1.A
          TAB1.B
          TAB1.C
          TAB1.D
          TAB2.A
FROM EMP TAB1, (SELECT TOP 1 A FROM EMP) TRAB2
WHERE TAB1.A = TAB2.A

 

메인->서브

서브->메인 둘다가능함

 

** 인라인 뷰 (=동적 뷰) : FROM절에 쓰여진 서브쿼리절

 

** FROM 절에서 이미 필터링해서 조인해서 끝냈기때문에, WHERE절의 EXISTS절의 단일행 연관서브쿼리는 의미가없고, 이미 조인된 테이블에 영향을 안줌

 

 

 

 

 

 

<활용>

** 이벤트시작일자가 2014.10.01과 같거나 큰 이벤트건수와 그 이벤트들을 기준으로 회원별 이메일 발송건수를 비교하는 SQL문

SELECT A.회원ID, A.회원명, A.이메일
FROM 회원 A
WHERE  EXISTS (SELECT 'X'
     FROM 이벤트 B, 메일발송 C
                     AND B.이벤트ID = C.이벤트ID
             AND A.회원ID = C.회원ID
     HAVING COUNT(*) < (SELECT COUNT(*)
                                                  FROM 이벤트
                                                  WHERE 시작일자 >= '2014.10.01'));

 

 

 

** 계층형구조 SQL

 

SELECT A.부서코드, A.부서명, A.상위부서코드, B.매출액, LVL
FROM (SELECT 부서코드, 부서명, 상위부서코드, LEVEL AS LVL
         FROM 부서
         START WITH 부서코드 = '120'
         CONNECT BY PRIOR 상위부서코드 = 부서코드
         UNION
         SELECT 부서코드, 부서명, 상위부서코드, LEVEL AS LVL
         FROM 부서
         START WITH 부서코드 = '120'
         CONNECT BY 상위부서코드 = PRIOR 부서코드) A LEFT OUTER JOIN 매출 B
ON     ( A.부서코드 = B.부서코드 )
ORDER BY A.부서코드;

 

 

 

 

** 평가대상상품에 대한 품질평가항목별 최종평가결과 추출하는 SQL문장

SELECT B.상품ID, B.상품명, C.평가항목ID, C.평가항목명, A.평가회차, A.평가등급, A.평가일자
FROM 평가결과 A, 평가대상상품 B, 품질평가항목 C
WHERE A.상품ID = B.상품ID
AND A.평가항목ID = C.평가항목ID
AND A.평가회차 = (SELECT MAX(X.평가회차)
                         FROM 평가결과 X
                         WHERE X.상품ID = B.상품ID
                         AND X.평가항목ID = C.평가항목ID);

 

 

 

 

 

오답

=> 이런식으로 SELECT문에 MAX로 다 적어버리면 각 컬럼에서 최대값만 나와서 값이 이상한 값이 도출됨

테이블이 이런식으로 있다고치면 상품ID = S002이고 평가항목ID = P001인 행들 중에,

컬럼에 평가회차를 MAX로 두면 평가회차가 3인 애가 나옴

컬럼에 평가등급을 MAX로 두면 평가등급이 C인 애가 나옴

=> 여기선 SELECT 절에 MAX를 두개 쓰면안됨 (SELECT절에 MAX 여러개 사용가능하지만, 이 문제에서는 안됨)

=> 아래처럼 한 ROW에 각 컬럼에서 최고인 값만 도출되서 짬뽕되서 나옴 (원래는 3번 row가 도출되야함)

 

이상한 결과값 도출

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

계속 업데이트 추가예정

728x90
LIST

'SQL' 카테고리의 다른 글

[Oracle, Mysql] 오라클(Oracle), Mysql Auto Commit 오토커밋설정  (1) 2024.03.18