<정리>
** 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가 도출되야함)
계속 업데이트 추가예정
'SQL' 카테고리의 다른 글
[Oracle, Mysql] 오라클(Oracle), Mysql Auto Commit 오토커밋설정 (1) | 2024.03.18 |
---|