SELECT 문 (Query)
- DQL(Query)
- 대상 : 하나 이상의 테이블, 뷰
- 데이터를 가져오는 데 사용
clause(절) 작성, 처리 순서
WITH
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
SELECT 절에서 사용하는 키워드
| 키워드 | 내용 |
|---|
| DISTINCT | 컬럼에 중복된 내용 배제 |
| ALL | 중복된 내용도 모두 조회 (생략되어 있음) |
| AS | 컬럼의 별칭(alias)을 부여 (생략할 수 있음) |
SELECT절 & FROM 절
SELECT *
FROM emp;
SELECT ename
, job
FROM emp;
- 문자열 합치기
- || 연산자
- concat(a, b) : a와 b 문자열을 합침
SELECT ename || ' ' ||job AS "Name_Job"
FROM emp;
- 숫자 연산 & null 값 처리
- + 연산자
- NVL(expr1, expr2) : expr1이 널일때 expr2로 변환
- NVL2(expr1, expr2, expr3) : expr1이 널이 아니면 expr2, 널이면 expr3로 변환
SELECT comm
, NVL(comm, 0)
, sal + NVL(comm, 0)
FROM emp;
WHERE 절
SELECT *
FROM emp
WHERE deptno = 10;
SELECT ibsadate, name
FROM insa
WHERE SUBSTR(ibsadate, 0, 2) = '98';
ORDER BY 절
- 정렬을 위한 절
- ASC : 오름차순 (생략 시 기본)
- DESC : 내림차순
SELECT deptno, empno, ename, hiredate
FROM emp
ORDER BY deptno , hiredate ;
ORDER BY deptno ASC, hiredate DESC;
WITH 절
- 서브쿼리 블럭을 미리 선언하여 나중에 반복하여 사용하기 위한 절
- 하나의 WITH절에 여러개 쿼리 블럭 사용 가능
- (WITH절이 없는) SELECT 문 이 쿼리 블럭 안에 포함
- 코딩을 간결하게 함
서브 쿼리
- SQL 문 부속된 또다른 SQL문
- 연산자 오른쪽에 위치
- ()로 묶음
- ORDER BY절을 사용할 수 없음
| 위치 | 이름 |
|---|
| FROM 절 | Inline view |
| WHERE 절 | Nested subquery |
| parent, child관계 | Correlated subquery |
WITH temp AS (
SELECT deptno, ename, sal + NVL(comm, 0) pay
FROM emp
WHERE deptno =30
)
SELECT t.*
FROM temp t
WHERE pay BETWEEN 1000 AND 2000;
- 인라인 뷰(inline view)
- FROM절 안에 서브쿼리
- 하나의 테이블 명처럼 사용되는 서브쿼리
SELECT t.*
FROM (
SELECT deptno, ename, sal + NVL(comm, 0) pay
FROM emp
WHERE deptno =30
) t
WHERE t.pay BETWEEN 1000 AND 2000;
- 일반 서브 쿼리의 경우, 결과를 메인 쿼리에서 이용
- 상관 서브 쿼리는 서브 쿼리 안에서 메인 쿼리의 값을 이용
- 서브쿼리에서 메인쿼리의 값 사용
- 그 서브쿼리의 결과를 메인 쿼리에서 사용
SELECT *
FROM emp e
WHERE sal = (SELECT MAX(sal) FROM emp WHERE deptno = e.deptno);
GROUP BY 절
- 레코드들의 그룹을 만들기 위한 절
- 그룹에 대한 정보를 한 행으로 표시
- 그룹 함수를 사용하는 쿼리문에서 자주 사용
SELECT MAX(sal) max_pay
FROM emp;
SELECT deptno,
MAX(sal) max_pay
FROM emp
GROUP BY deptno;
ROLLUP, CUBE
- GROUP BY 절에 쓰이는 연산자
- 그룹에 대해 부분합을 구하는 연산자
- ROLLUP은 (GROUP BY 컬럼 수) + 1 개의 부분합 출력
- deptno별 - job별 부분합
- deptno별 부분합
- 전체의 부분합
SELECT deptno, job, count(*)
FROM emp
GROUP BY ROLLUP (deptno, job);
| deptno | clerk | salesman | manager | analyst | president | 부분합 |
|---|
| 10 | 1 | - | 1 | - | 1 | 3 |
| 20 | 1 | - | 1 | 1 | - | 3 |
| 10 | 1 | 4 | 1 | - | - | 6 |
| 부분합 | - | - | - | - | - | 12 |
- CUBE는 (GROUP BY 컬럼 수) * 2 개의 부분합 출력
- deptno별 - job별 부분합
- deptno별 부분합
- job별 부분합
- 전체의 부분합
SELECT deptno, job, count(*)
FROM emp
GROUP BY CUBE (deptno, job);
| deptno | clerk | salesman | manager | analyst | president | 부분합 |
|---|
| 10 | 1 | - | 1 | - | 1 | 3 |
| 20 | 1 | - | 1 | 1 | - | 3 |
| 10 | 1 | 4 | 1 | - | - | 6 |
| 부분합 | 3 | 4 | 3 | 1 | 1 | 12 |
HAVING 절
- GROUP BY 절에서 그룹화한 그룹에 대한 조건을 주는 절
- 반드시 GROUP BY 뒤에 위치 (단독으로는 사용 불가)
- WHERE절과 달리 그룹 함수 같이 그룹에 대한 조건이 가능
SELECT deptno, MAX(sal)
FROM emp
WHERE EXTRACT(YEAR FROM hiredate) = 1981;
GROUP BY deptno
HAVING COUNT(*) >= 2
ORDER BY deptno;