본문 바로가기
🗄️ DB_이야기/# ⚡SQL

[SQL] SQL 기본 개념

by gwon_s 2026. 4. 3.

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단계를 거쳐 데이터를 처리합니다.

  1. FROM (+ JOIN): 어떤 테이블에서 데이터를 가져올지 결정합니다. (가장 먼저 데이터의 원천을 찾음)
  2. WHERE: 가져온 전체 데이터 중 필요한 행만 필터링합니다. (데이터 다이어트)
  3. GROUP BY: 남은 데이터를 특정 기준(컬럼)으로 그룹화합니다.
  4. HAVING: 그룹화된 결과 중 특정 조건(집계 결과 등)에 맞는 그룹만 남깁니다.
  5. SELECT: 최종적으로 어떤 컬럼을 보여줄지 선택합니다. (여기서 별칭이 부여됨)
  6. ORDER BY: 선택된 데이터를 정렬합니다. (별칭 사용 가능)
  7. 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