SQL(Structured Query Language, 구조화된 질의 언어)은 데이터베이스에서 데이터를 저장, 조회, 수정, 삭제할 때 사용하고, 데이터베이스 자체의 성능 유지관리, 최적화에 사용되는 언어입니다.
쉽게 말해 데이터베이스를 다루기 위해 쓰는 언어라고 할 수 있습니다.
SQL 종류
| 구분 | 풀이 | 주요 명령어 | 설명 |
| DDL(Data Definition Language) | 데이터 정의어 | CREATE, ALTER, DROP, TRUNCATE, RENAME | 테이블 공간 자체를 만들고 수정 |
| DML(Data Manipulation Language) | 데이터 조작어 | SELECT, INSERT, UPDATE, DELETE | 테이블 안의 데이터를 다룸 |
| DCL(Data Control Language) | 데이터 제어어 | GRANT, REVOKE | 유저의 권한을 관리 |
| TCL(Transaction Control Language) | 트랜잭션 제어어 | COMMIT, ROLLBACK, SAVEPOINT | 트랜잭션을 관리 |
SQL 문법
DDL (Data Definition Language) - 데이터 정의어
더보기
CREATE 문법 - 테이블 생성
CREATE TABLE [테이블명] (
[컬럼명1] [데이터타입] [제약조건],
[컬럼명2] [데이터타입], ...
);
CREATE TABLE my_blog (
post_id NUMBER(10) PRIMARY KEY, -- 숫자형, 중복불가/필수입력
title VARCHAR2(100) NOT NULL, -- 가변문자형(100바이트), 필수입력
content CLOB, -- 대용량 텍스트
reg_date DATE DEFAULT SYSDATE -- 날짜형, 기본값은 현재시간
);
DML(Data Manipulation Language) - 데이터 조작어
더보기
INSERT - 데이터 삽입
INSERT INTO [테이블명] ([컬럼1], [컬럼2]) VALUES ([값1], [값2]);
INSERT INTO my_blog (post_id, title, content)
VALUES (1, '포스팅', 'SQL!');
UPDATE - 데이터 수정
UPDATE [테이블명] SET [컬럼] = [바꿀값] WHERE [조건];
UPDATE my_blog
SET title = '수정된 제목'
WHERE post_id = 1; -- 특정 행만 지정 (안 쓰면 모든 행이 바뀜!)
DELETE - 데이터 삭제
DELETE FROM [테이블명] WHERE [조건];
DELETE FROM my_blog
WHERE post_id = 1; -- 특정 행만 삭제
DCL(Data Control Language) - 데이터 제어어
더보기
GRANT - 권한 부여
GRANT [권한명] ON [대상객체] TO [사용자];
GRANT SELECT, UPDATE ON my_blog TO guest_user;
REVOKE - 권한 회수
REVOKE [권한명] ON [대상객체] FROM [사용자];
REVOKE UPDATE ON my_blog FROM guest_user;
TCL(Transaction Control Language) - 트랜잭션 제어어
더보기
COMMIT - 작업한 내용 저장
INSERT INTO my_blog VALUES (2, 'TCL 테스트', '커밋 전', SYSDATE);
COMMIT; -- '지금까지 한 작업 진짜 저장해!'
ROLLBACK - 작업한 내용 마지막 커밋 시점으로 되돌리기
INSERT INTO my_blog VALUES (2, 'TCL 테스트', '커밋 전', SYSDATE);
ROLLBACK; -- '아차, 실수했다! 마지막 커밋 시점으로 다 되돌려!'
SAVEPOINT - 롤백 기준점 지정
SAVEPOINT point1; -- '여기까진 안전해, 중간 저장!'
SELECT 절
SELECT 구조
SELECT -- (5) 어떤 컬럼을 출력할 것인가?
[DISTINCT] { * | 컬럼명 | 표현식 [AS 별칭] }, ...
FROM -- (1) 어느 테이블에서 데이터를 가져올 것인가?
[사용자명.]테이블명 [별칭], ...
[JOIN] -- (1) 여러 테이블을 연결할 것인가?
테이블명 [별칭] ON 조인조건
WHERE -- (2) 어떤 조건으로 행(Row)을 걸러낼 것인가?
조건식 (비교, 범위, 포함, NULL 여부 등)
GROUP BY -- (3) 데이터를 어떤 기준으로 그룹화할 것인가?
컬럼명, ...
HAVING -- (4) 그룹화된 결과 중 어떤 그룹만 남길 것인가?
그룹 조건식 (집계함수 포함 가능)
ORDER BY -- (6) 최종 결과를 어떤 순서로 정렬할 것인가?
{ 컬럼명 | 별칭 | 컬럼순번 } [ASC | DESC];
1. FROM (대상 테이블)
- 작성 내용: 데이터를 뽑아올 원천 테이블 이름을 적습니다.
- 팁: 테이블명이 길면 EMP E처럼 별칭(Alias)을 주어 쿼리를 간결하게 만듭니다.
2. WHERE (행 필터링)
- 작성 내용: SAL > 3000, ENAME LIKE 'A%' 같은 조건을 적습니다.
- 주의: 집계 함수(SUM, AVG 등)는 여기서 직접 사용할 수 없습니다.
3. GROUP BY (그룹화)
- 작성 내용: 데이터를 묶을 기준 컬럼을 적습니다.
- 원리: 같은 값을 가진 행들을 하나로 합쳐서 통계를 낼 준비를 합니다.
4. HAVING (그룹 필터링)
- 작성 내용: COUNT(*) > 5 처럼 그룹화된 이후의 조건을 적습니다.
- 차이: WHERE는 개별 행을, HAVING은 완성된 그룹을 걸러냅니다.
5. SELECT (열 선택)
- 작성 내용: 보고 싶은 컬럼명을 나열합니다. *는 모든 컬럼을 의미합니다.
- 팁: AS "별명"을 써서 출력 화면의 헤더 이름을 바꿀 수 있습니다.
6. ORDER BY (정렬)
- 작성 내용: ASC(오름차순, 기본값) 또는 DESC(내림차순)를 지정합니다.
- 원리: 모든 연산이 끝난 후 가장 마지막에 데이터를 줄 세웁니다.
SELECT 실행 순서
옵티마이저는 아래의 7단계를 거쳐 데이터를 처리합니다.
- FROM (+ JOIN): 어떤 테이블에서 데이터를 가져올지 결정합니다. (가장 먼저 데이터의 원천을 찾음)
- WHERE: 가져온 전체 데이터 중 필요한 행만 필터링합니다. (데이터 다이어트)
- GROUP BY: 남은 데이터를 특정 기준(컬럼)으로 그룹화합니다.
- HAVING: 그룹화된 결과 중 특정 조건(집계 결과 등)에 맞는 그룹만 남깁니다.
- SELECT: 최종적으로 어떤 컬럼을 보여줄지 선택합니다. (여기서 별칭이 부여됨)
- ORDER BY: 선택된 데이터를 정렬합니다. (별칭 사용 가능)
- LIMIT / OFFSET: 최종 출력 개수를 제한합니다.
주요 집계 함수
| 함수 | 설명 | 특징 |
| SUM | 합계 | 숫자형 컬럼에만 사용가능 |
| AVG | 평균 | NULL 제외 후 평균 계산 |
| COUNT | 개수 | COUNT(*)는 전체 행, COUNT(컬럼)은 NULL 제외 개수 |
| MAX / MIN | 최대 / 최소 | 숫자, 문자, 날짜형 모두 사용 가능 |
| STDDEV / VARIANCE | 표준편차 / 분산 | 통계적 분석 시 활용 |
👇사용 예시
더보기
EMP 테이블
| EMPNO(사번) | ENAME(성명) | SAL(급여) | COMM(상여) |
| 101 | KING | 5000 | 500 |
| 102 | SCOTT | 4000 | (NULL) |
| 103 | ADAMS | 3000 | 300 |
| 104 | MILLER | (NULL) | (NULL) |
집계 함수 실행
SELECT
SUM(SAL) AS SUM_SAL, -- 합계
AVG(SAL) AS AVG_SAL, -- 평균
COUNT(*) AS CNT_ALL, -- 전체 행수
COUNT(SAL) AS CNT_SAL, -- SAL이 NULL이 아닌 행수
MAX(SAL) AS MAX_SAL, -- 최대값
MIN(SAL) AS MIN_SAL, -- 최소값
ROUND(STDDEV(SAL), 2) AS STD_SAL, -- 표준편차
VARIANCE(SAL) AS VAR_SAL -- 분산
FROM EMP;
--[출력 결과 - Result Output]
-----------------------------------------------------------------------------------------
SUM_SAL | AVG_SAL | CNT_ALL | CNT_SAL | MAX_SAL | MIN_SAL | STD_SAL | VAR_SAL
-----------------------------------------------------------------------------------------
12000 | 4000 | 4 | 3 | 5000 | 3000 | 1000 | 1000000
-----------------------------------------------------------------------------------------
그룹 함수
| 함수 | 설명 | 특징 |
| GROUP BY 절 | 데이터를 소그룹으로 나누고 각 그룹별로 집계 결과를 산출 | 정렬(Sort), 해시(Hash) 알고리즘이 사용되어 CPU와 PGA 자원을 소모 |
| ROLLUP | 계층적인 구조로 소계와 총계 산출 | 순서가 중요 |
| CUBE | 결합 가능한 모든 조합에 대해 다차원 집계 | 자원 소모가 심함 |
| GROUPING SETS | 특정 항목들에 대해서만 평면적으로 집계 | 특정 항목들에 대해서만 평면적으로 집계 |
👇사용 예시
더보기
테이블
| DEPTNO | JOB | SAL |
| 101 | CLERK | 1000 |
| 102 | MANAGER | 2000 |
| 103 | CLERK | 1500 |
| 104 | MANAGER | 2500 |
각 함수별 실행 및 결과
-- [A] 기본 GROUP BY: 가장 낮은 레벨의 집계만 수행
SELECT DEPTNO, JOB, SUM(SAL) AS SUM_SAL FROM SAMPLE_DATA GROUP BY DEPTNO, JOB;
-- [출력 결과 비교 - Result Comparison]
-- [A] GROUP BY (단순 집계)
DEPTNO | JOB | SUM_SAL
-------|---------|--------
10 | CLERK | 1000
10 | MANAGER | 2000
20 | CLERK | 1500
20 | MANAGER | 2500
-- [B] ROLLUP: 계층적 소계 (부서별 소계 + 전체 합계)
SELECT DEPTNO, JOB, SUM(SAL) AS SUM_SAL FROM SAMPLE_DATA GROUP BY ROLLUP(DEPTNO, JOB);
-- [출력 결과 비교 - Result Comparison]
-- [B] ROLLUP (계층 소계) - JOB이 NULL인 행이 부서소계, 둘 다 NULL이면 총계
DEPTNO | JOB | SUM_SAL
-------|---------|--------
10 | CLERK | 1000
10 | MANAGER | 2000
10 | (NULL) | 3000 <-- 10번 부서 소계
20 | CLERK | 1500
20 | MANAGER | 2500
20 | (NULL) | 4000 <-- 20번 부서 소계
(NULL) | (NULL) | 7000 <-- 총 합계
-- [C] CUBE: 모든 가능한 조합의 소계 (부서별, 직업별, 전체 합계)
SELECT DEPTNO, JOB, SUM(SAL) AS SUM_SAL FROM SAMPLE_DATA GROUP BY CUBE(DEPTNO, JOB);
-- [출력 결과 비교 - Result Comparison]
-- [C] CUBE (다차원 집계) - 부서별뿐만 아니라 JOB별(10/20번 합친) 소계도 나옴
DEPTNO | JOB | SUM_SAL
-------|---------|--------
(NULL) | (NULL) | 7000 <-- 총 합계
(NULL) | CLERK | 2500 <-- 전 부서 CLERK 합계
(NULL) | MANAGER | 4500 <-- 전 부서 MANAGER 합계
10 | (NULL) | 3000
10 | CLERK | 1000
10 | MANAGER | 2000
20 | (NULL) | 4000
20 | CLERK | 1500
20 | MANAGER | 2500
-- [D] GROUPING SETS: 지정한 항목만 평면적으로 집계
SELECT DEPTNO, JOB, SUM(SAL) AS SUM_SAL FROM SAMPLE_DATA GROUP BY GROUPING SETS(DEPTNO, JOB);
-- [출력 결과 비교 - Result Comparison]
-- [D] GROUPING SETS (선택 집계) - 부서별 합계와 직업별 합계만 딱 보여줌
DEPTNO | JOB | SUM_SAL
-------|---------|--------
10 | (NULL) | 3000
20 | (NULL) | 4000
(NULL) | CLERK | 2500
(NULL) | MANAGER | 4500
'🗄️ DB_이야기 > # ⚡SQL' 카테고리의 다른 글
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 과일로 만든 아이스크림 고르기(SELECT) (0) | 2026.04.13 |
|---|---|
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 12세 이하인 여자 환자 목록 출력하기(SELECT) (1) | 2026.04.13 |
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 인기있는 아이스크림(SELECT) (0) | 2026.04.10 |
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 조건에 맞는 도서 리스트 출력하기(SELECT) (0) | 2026.04.10 |
| 🚀[SQL 알고리즘 문제 풀이] Programmers : 평균 일일 대여 요금 구하기(SELECT) (1) | 2026.04.10 |