SQL코딩테스트

[SQL] SQL 코딩테스트 10분전 외워야 할 공식들

Nuri-KSLV-II 2025. 10. 11. 20:49

SQL 명령어 실행 순서

실제 실행 순서

  1. FROM - 테이블 지정 및 조인
  2. WHERE - 행 필터링 (집계 전)
  3. GROUP BY - 그룹화
  4. HAVING - 그룹 필터링 (집계 후)
  5. SELECT - 컬럼 선택 및 계산
  6. DISTINCT - 중복 제거
  7. ORDER BY - 정렬
  8. LIMIT/OFFSET - 결과 개수 제한

 

예시

SELECT department, COUNT(*) as emp_count
FROM employees
WHERE salary > 3000 -- 집계함수 사용 불가
GROUP BY department
HAVING COUNT(*) > 5 -- 집계함수 사용 가능
ORDER BY emp_count DESC
LIMIT 10;
  1. FROM employees - employees 테이블 가져오기
  2. WHERE salary > 3000 - 급여 3000 초과인 직원만 필터링
  3. GROUP BY department - 부서별로 그룹화
  4. HAVING COUNT(*) > 5 - 직원 수가 5명 초과인 그룹만 선택
  5. SELECT department, COUNT(*) - 부서명과 직원 수 계산
  6. ORDER BY emp_count DESC - 직원 수 내림차순 정렬
  7. LIMIT 10 - 상위 10개만 반환

 

CASE WHEN 조건문

CASE 
    WHEN 조건1 THEN 결과1
    WHEN 조건2 THEN 결과2
    ELSE 기본결과 -- 생략 가능 생략 시 자동으로 NULL
END

 

예시 - 급여 등급 분류

SELECT 
    name,
    salary,
    CASE 
        WHEN salary >= 7000 THEN '고급'
        WHEN salary >= 5000 THEN '중급'
        ELSE '초급'
    END AS grade
FROM employees;

 

 

문자열 처리 - CONCAT 함수

-- CONCAT: 여러 문자열 연결
SELECT CONCAT('Hello', ' ', 'World');  -- 'Hello World'

-- CONCAT_WS: 구분자를 사용한 연결 (Concat With Separator)
SELECT CONCAT_WS('-', '2024', '10', '26');  -- '2024-10-26'

-- NULL 처리: 하나라도 NULL이면 결과가 NULL
SELECT CONCAT('Hello', NULL, 'World');  -- NULL

 

DATE 처리

-- 날짜 추출
YEAR(date)          -- 연도
MONTH(date)         -- 월
DAY(date)           -- 일
QUARTER(date)       -- 분기

-- 현재 날짜
CURDATE()           -- 오늘 날짜
NOW()               -- 현재 날짜+시간

-- 포맷팅
DATE_FORMAT(date, '%Y-%m-%d')  -- 날짜 형식 변환

-- 연산
DATE_ADD(date, INTERVAL n DAY/MONTH/YEAR)  -- 날짜 더하기
DATEDIFF(date1, date2)                     -- 날짜 차이

-- 변환
DATE(datetime)      -- datetime → date
STR_TO_DATE(str, format)  -- 문자열 → 날짜

-- 비교 (성능 중요!)
✅ WHERE date >= '2021-01-01' AND date < '2022-01-01' --인덱스 사용가능
⚠️ WHERE YEAR(date) = 2021 --인덱스 사용불가

 

LIKE

1. % 와일드카드 (여러 문자)

-- 'A'로 시작하는 모든 문자열
SELECT * FROM ITEM_INFO
WHERE NAME LIKE 'A%';

-- 'A'로 끝나는 모든 문자열
SELECT * FROM ITEM_INFO
WHERE NAME LIKE '%A';

-- 'A'가 포함된 모든 문자열
SELECT * FROM ITEM_INFO
WHERE NAME LIKE '%A%';

-- 'A'로 시작하고 'Z'로 끝나는 문자열
SELECT * FROM ITEM_INFO
WHERE NAME LIKE 'A%Z';

 

2. _ 와일드카드 (한 글자)

-- 정확히 3글자인 문자열
SELECT * FROM ITEM_INFO
WHERE NAME LIKE '___';

-- 'A'로 시작하는 3글자 문자열
SELECT * FROM ITEM_INFO
WHERE NAME LIKE 'A__';

-- 두 번째 글자가 'A'인 문자열
SELECT * FROM ITEM_INFO
WHERE NAME LIKE '_A%';

 

 

NULL 처리

예시

https://school.programmers.co.kr/learn/courses/30/lessons/293259

-- 1. CASE 직접 사용 (가장 간단) ✅
SELECT ROUND(AVG(CASE WHEN LENGTH IS NULL THEN 10 ELSE LENGTH END), 2) AS AVERAGE_LENGTH
FROM FISH_INFO;

-- 2. COALESCE 사용 (더 간결) ✅
SELECT ROUND(AVG(COALESCE(LENGTH, 10)), 2) AS AVERAGE_LENGTH
FROM FISH_INFO;

 

서브쿼리

1. WHERE 절 서브쿼리

-- 단일 값 비교
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

-- IN 사용
SELECT name, department_id
FROM employees
WHERE department_id IN (SELECT id FROM departments WHERE location = 'Seoul');

-- EXISTS 사용
SELECT name
FROM employees e
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.employee_id = e.id);

 

2. FROM 절 서브쿼리

SELECT dept_name, avg_salary
FROM (
    SELECT department_id, AVG(salary) as avg_salary
    FROM employees
    GROUP BY department_id
) dept_avg
JOIN departments d ON dept_avg.department_id = d.id;

 

3. SELECT 절 서브쿼리

SELECT 
    name,
    salary,
    (SELECT AVG(salary) FROM employees) as company_avg,
    (SELECT COUNT(*) FROM orders WHERE employee_id = e.id) as order_count
FROM employees e;

 

 

DISTINCT

-- 중복 제거된 단일 컬럼
SELECT DISTINCT department_id
FROM employees;

-- 중복 제거된 개수
SELECT COUNT(DISTINCT department_id) as dept_count
FROM employees;

-- 부서별 고유한 직책 수
SELECT 
    department_id,
    COUNT(DISTINCT job_title) as unique_jobs
FROM employees
GROUP BY department_id;

-- DISTINCT 대신 GROUP BY 사용 (때로는 더 효율적)
SELECT department_id
FROM employees
GROUP BY department_id;