테이블 데이터를 조회할 때 사용하는 명령어
SELECT (DISTINCT) column_name (ALIAS)
FROM table_name;
SELECT * 로 모든 컬럼을 조회할 수 있다
SELECT salary * 100 과 같이 산술식을 넣어 출력할 수 있다
SELECT name || ' ' || title 과 같이 다른 컬럼이나 값을 연결해서 하나의 컬럼으로 출력할 수 있다
쿼리 실행 순서
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
데이터 정렬 시 사용하는 명령어
SELECT (DISTINCT) column_name (ALIAS)
FROM table_name
ORDER BY [column_name | expression] [ASC | DESC];
조건에 맞는 행을 선택하여 조회할 때 사용하는 명령어
SELECT (DISTINCT) column_name (ALIAS)
FROM table_name
WHERE [column_name | expression] [operator] [value]
filter() 함수와 유사| 연산자 | 의미 | 예시 |
|---|---|---|
AND | 그리고 | salary > 3000 AND dept_id = 10 |
OR | 또는 | job_id = 'MANAGER' OR job_id = 'CLERK' |
NOT | 부정 | NOT (salary < 5000) |
| 연산자 | 의미 | 예시 |
|---|---|---|
= | 같다 | dept_id = 10 |
!= 또는 <> | 같지 않다 | salary != 5000 |
> | 크다 | age > 30 |
< | 작다 | score < 70 |
>= | 크거나 같다 | salary >= 3000 |
<= | 작거나 같다 | hire_date <= SYSDATE |
| 연산자 / 키워드 | 의미 | 예시 |
|---|---|---|
BETWEEN ... AND ... | 범위 내 포함 (양 끝 포함) | score BETWEEN 70 AND 90 |
IN (...) | 지정한 목록 중 하나와 일치 | dept_id IN (10, 20, 30) |
LIKE | 패턴(문자열) 일치 여부 검사 | name LIKE 'J%' |
IS NULL | NULL 여부 비교 | phone IS NULL |
EXISTS (서브쿼리) | 서브쿼리 결과가 존재할 경우 TRUE | WHERE EXISTS (SELECT 1 FROM emp WHERE dept_id = 10) |
ANY (서브쿼리) | 서브쿼리 결과 중 하나라도 만족하면 TRUE | salary > ANY (SELECT salary FROM emp WHERE dept_id = 10) |
ALL (서브쿼리) | 서브쿼리 결과 모두를 만족해야 TRUE | salary > ALL (SELECT salary FROM emp WHERE dept_id = 10) |
NOT IN은 NULL 값이 있을 경우 FALSE가 되므로 NOT EXISTS 로 대체할 수 있다
FROM 과 WHERE 에 대한 결과 집합에 대해 grouping
2차원인 table을 grouping 하면 1차원인 row로 표현 가능
SELECT dept_id, region_id, AVG(salary)
FROM s_dept
GROUP BY dept_id, region_id
HAVING AVG(salary) > 2000
SELECT 에 그룹 함수가 오면 나머지 컬럼들은 GROUP BY 절에 기술되어야 한다GROUP BY 에 dept_id, region_id 둘 중 어느 하나도 빠지면 안된다WHERE 가 아닌 HAVING 에 기술해야 한다dept_id 가 메인 그룹 region_id 가 서브그룹이다하나 이상의 테이블로부터 연관된 데이터를 매핑하여 하나의 테이블처럼 만든다
등치 조건
일반적으로 PK, FK 관계에 의해 JOIN이 성립한다
SELECT *
FROM table1, table2
WHERE table1.column1 = table2.column2;
= 연산자 외의 다른 연산자를 사용하여 JOIN하는 방법
SELECT *
FROM table1, table2
WHERE table1.column1 BETWEEN table2.column2 AND table2.column3;
column2 와 column3 사이에 있는 column1 값들이 table2 의 row에 매핑된다
(+) 연산자가 있는 쪽에 데이터가 없으면 NULL로 표시된다
SELECT *
FROM table1, table2
WHERE table1.column1 (+) = table2.column2;
IN, OR 는 사용 불가(+) 연산자를 위치시킨다하나의 테이블을 여러 개인 것처럼 사용 가능
SELECT *
FROM s_emp e1, s_emp e2
WHERE e1.manager_id = e2.id;
두 개의 쿼리 결과에 대해 집합 연산을 수행한다
ORDER BY 는 마지막에 한 번만 기술한다UNION ALL 을 제외한 연산자는 교집합을 찾아야 하므로 성능이 떨어진다SELECT 문 안에 포함된 또 다른 SELECT 문
ORDER BY 를 포함하지 않는다=, >, >=, <, <=, <>IN, NOT INSELECT 외에도 CREATE, INSERT, UPDATE, DELETE 에서 사용 가능하다scalar subquery 외에는 SELECT 에서 사용이 불가하다
결과 행과 열이 하나인 서브쿼리. 즉, 단 하나의 데이터를 조회하는 쿼리
단일행 연산자를 사용한다
SELECT *
FROM s_emp
WHERE dept_id = ( SELECT dept_id FROM s_emp WHERE name = '김정미' );
결과 행은 여러개, 열은 하나인 서브쿼리
복수행 연산자를 사용한다
SELECT *
FROM s_emp
WHERE dept_id IN ( SELECT id FROM s_dept WHERE region_id = 3 );
결과 행과 열이 여러 개인 서브 쿼리
복수행 연산자를 사용한다
pair-wise : 두 항목씩 짝지어 비교하거나 계산
SELECT *
FROM s_emp
WHERE (salary, dept_id) IN -- pair-wise
( SELECT MIN(salary), dept_id
FROM s_emp
GROUP BY dept_id );
FROM 에 사용하는 서브쿼리
데이터 양이 많아 일부분에 대해서 조회할 때 사용
SELECT *
FROM ( SELECT * FROM s_emp WHERE title = '사원' ) e, s_dept d
WHERE e.dept_id = d.id;
두 가지 정의가 있다
실제로 중첩된 경우
SELECT emp_name
FROM employees
WHERE dept_id = (
SELECT dept_id
FROM departments
WHERE location_id = (
SELECT location_id
FROM locations
WHERE city = 'Seoul'
)
);
Correlated Subquery : 바깥 쿼리의 값을 참조해서 사용하는 서브쿼리
SELECT emp_name
FROM employees e
WHERE salary > (
SELECT AVG(salary)
FROM employees
WHERE dept_id = e.dept_id -- 바깥 쿼리의 employees 테이블을 참조
);
바깥 쿼리의 값(e.dpet_id)가 남지 않을 때까지 반복해서 서브쿼리를 실행한다