카테고리 없음

[유레카 / 백엔드] TIL - 5 (JAVA)

coding-quokka101 2025. 10. 1. 17:56

📘 MySQL 데이터베이스 학습 정리 — 집계 함수, GROUP BY, 서브쿼리, 조인, 실무 활용까지

현재 제가 공부하고 있는 교재는 **「MySQL 데이터베이스 개론과 실습 2판」**입니다.
이 책은 단순히 SQL 문법만 나열하는 것이 아니라, 실습 예제 중심으로 진행되기 때문에 직접 쿼리를 작성하고 실행해보면서 학습할 수 있다는 장점이 있습니다.
특히 실무에서 필수적으로 쓰이는 집계 함수, GROUP BY, 서브쿼리, 조인 같은 주제를 집중적으로 다루고 있어, 회사 전산 관리나 데이터 분석, 코딩 테스트 문제 풀이에도 큰 도움이 됩니다.

 

MySQL로 배우는 데이터베이스 개론과 실습-2판 - 영풍문고


1️⃣ 집계 함수와 GROUP BY

집계 함수는 데이터를 요약하는 가장 기본적인 도구입니다.

  • COUNT: 행 개수
  • SUM: 합계
  • AVG: 평균
  • MAX / MIN: 최대, 최소

예제: 고객별 총 주문 건수와 매출액

SELECT custid, COUNT(*) cnt, SUM(saleprice) total
FROM orders
GROUP BY custid
HAVING SUM(saleprice) >= 10000
ORDER BY total DESC;

 

실무에서 중요한 포인트:

  • GROUP BY에 없는 비집계 컬럼을 SELECT에 올리는 것은 비표준 → 결과가 DB 엔진마다 달라질 수 있으므로 피해야 함.
  • 대량 데이터에서 집계를 자주 한다면 집계 전용 인덱스OLAP 시스템 도입도 고려.

2️⃣ 서브쿼리 (Subquery)

단일행 서브쿼리

SELECT * FROM book WHERE price = (SELECT MAX(price) FROM book);

하나의 값만 반환하는 경우.

다중행 서브쿼리

SELECT * FROM customer 
WHERE custid IN (SELECT DISTINCT custid FROM orders);

집합에 속하는지 확인할 때 유용.

상관 서브쿼리

SELECT *
FROM book b1
WHERE b1.price > (
  SELECT AVG(b2.price) 
  FROM book b2 
  WHERE b2.publisher = b1.publisher
);

메인쿼리의 컬럼을 참조. 행마다 실행되므로 직관적이지만 성능은 불리.


3️⃣ 조인 (JOIN)

조인은 여러 테이블을 가로로 합치는 방법입니다.
상관 서브쿼리로도 해결 가능한 문제를 JOIN + GROUP BY로 바꾸면 보통 더 효율적입니다.

SELECT b1.*
FROM book b1
JOIN (
  SELECT publisher, AVG(price) avg_price
  FROM book
  GROUP BY publisher
) t ON b1.publisher = t.publisher
WHERE b1.price > t.avg_price;

 


4️⃣ 서브쿼리 vs 조인 — 차이와 선택 기준

구분 서브쿼리 조인

직관성 읽기 쉬움 (특히 상관 서브쿼리) SQL 구조가 복잡해질 수 있음
성능 상관 서브쿼리는 행마다 실행 → 느릴 수 있음 옵티마이저가 효율적으로 실행 → 보통 빠름
사용 목적 값 비교, 존재 여부 확인 (IN, EXISTS) 두 테이블을 동시에 출력하거나 집계 비교
리스크 NOT IN + NULL → 예기치 않은 결과 NULL 처리 문제 적음
실무 권장 단순 비교/조건 확인 시 대량 데이터 분석, 집계, 컬럼 다중 출력 시

👉 핵심:

  • “값 비교” → 서브쿼리
  • “결과를 합쳐서 보여줘야” → 조인
  • 성능이 중요하면 항상 조인 우선 고려

5️⃣ EXISTS vs IN vs JOIN

  • IN (subquery) : 서브쿼리 결과 집합에 포함 여부 검사
  • EXISTS (subquery) : 조건 만족 행이 존재하는지만 확인 → 보통 상관 서브쿼리
  • JOIN : 실제 데이터를 합쳐서 출력

실무에서는 단순 존재 여부 확인은 EXISTS가 효율적인 경우가 많습니다.
NOT IN은 NULL이 있으면 결과가 꼬이므로 NOT EXISTS로 바꾸는 습관을 들이는 것이 안전합니다.


6️⃣ UPDATE / DELETE 에서의 서브쿼리와 조인

-- 서브쿼리 방식
UPDATE orders o
SET o.bname = (SELECT b.bookname FROM book b WHERE b.bookid = o.bookid);

-- 조인 방식 (권장)
UPDATE orders o
JOIN book b ON o.bookid = b.bookid
SET o.bname = b.bookname;

DELETE도 마찬가지입니다. 실무에서는 JOIN 기반 UPDATE/DELETE가 더 명확하고 성능도 안정적입니다.


7️⃣ UNION vs UNION ALL

SELECT name FROM customer WHERE address LIKE '대한%'
UNION ALL
SELECT name FROM customer WHERE custid IN (SELECT custid FROM orders);
  • UNION : 중복 제거 → 비용 발생
  • UNION ALL : 단순 합치기, 빠름

실무에서는 불필요한 중복 제거를 하지 않는 UNION ALL이 선호됩니다.


8️⃣ 실무에서 자주 부딪히는 문제들

  • NULL 처리 : NOT IN은 NULL 때문에 항상 false가 될 수 있음 → 반드시 NOT EXISTS 고려
  • 상관 서브쿼리 성능 : 소량 데이터 → 괜찮음, 대량 데이터 → 반드시 JOIN으로 리팩터링 검토
  • 인덱스 활용 : JOIN, WHERE, GROUP BY 컬럼은 인덱스가 없으면 쿼리가 급격히 느려짐
  • OLTP vs OLAP : 실시간 트랜잭션 시스템에서는 복잡한 서브쿼리/집계보다 단순 쿼리 + 사전 집계 테이블을 두는 경우가 많음

✍️ 오늘의 정리

  • 집계 함수 + GROUP BY : 데이터를 요약하는 핵심
  • HAVING : 그룹화된 결과에 조건을 주는 유일한 방법
  • 서브쿼리 : 단일행, 다중행, 상관 서브쿼리
  • 조인 : 실무에서 가장 많이 쓰이고, 성능상 유리
  • 서브쿼리 vs 조인 : 직관성 vs 성능 → 상황에 맞게 선택
  • 실무 팁 : NOT IN 대신 NOT EXISTS, UPDATE/DELETE 조인 사용, UNION ALL 권장

👉 오늘은 단순 문법을 넘어서, 왜 JOIN이 권장되는지, NULL과 NOT IN의 위험성, 집계 시 성능 이슈까지 배웠습니다. 이런 내용들은 실제 회사 전산실이나 백엔드 개발자가 쿼리를 작성할 때 반드시 부딪히는 문제이기도 해서 매우 중요한 학습이었습니다.