1. .카테고리별 도서 판매량
https://school.programmers.co.kr/learn/courses/30/lessons/144855
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
CATEGORY,
SUM(SALES) AS TOTAL_SALES
FROM BOOK_SALES AS S
LEFT JOIN BOOK AS B ON S.BOOK_ID = B.BOOK_ID
WHERE SALES_DATE LIKE '2022-01-%'
GROUP BY CATEGORY
ORDER BY CATEGORY;
2. 오랜 기간 보호한 동물(1)
https://school.programmers.co.kr/learn/courses/30/lessons/59044
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
NAME,
DATETIME
FROM
(SELECT
INS.*
FROM ANIMAL_INS AS INS
LEFT JOIN ANIMAL_OUTS AS OUTS ON INS.ANIMAL_ID = OUTS.ANIMAL_ID
WHERE OUTS.ANIMAL_ID IS NULL) AS T
ORDER BY DATETIME
LIMIT 3;
3. 조건별로 분류하여 주문상태 출력하기
https://school.programmers.co.kr/learn/courses/30/lessons/131113
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
ORDER_ID,
PRODUCT_ID,
DATE_FORMAT(OUT_DATE, '%Y-%m-%d') AS OUT_DATE,
(CASE
WHEN OUT_DATE > '2022-05-01' THEN '출고대기'
WHEN OUT_DATE <= '2022-05-01' THEN '출고완료'
ELSE '출고미정'
END) AS `출고여부`
FROM FOOD_ORDER
ORDER BY ORDER_ID;
4. 대여 기록이 존재하는 자동차 리스트 구하기
https://school.programmers.co.kr/learn/courses/30/lessons/157341
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
DISTINCT(H.CAR_ID)
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY AS H
LEFT JOIN CAR_RENTAL_COMPANY_CAR AS C
ON H.CAR_ID = C.CAR_ID
WHERE (CAR_TYPE = '세단') AND (START_DATE LIKE '2022-10%')
ORDER BY H.CAR_ID DESC;
5. 있었는데요 없었습니다
https://school.programmers.co.kr/learn/courses/30/lessons/59043
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
OUTS.ANIMAL_ID,
OUTS.NAME
FROM ANIMAL_OUTS AS OUTS
JOIN ANIMAL_INS AS INS ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
WHERE OUTS.DATETIME < INS.DATETIME
ORDER BY INS.DATETIME;
6. 오랜 기간 보호한 동물(2)
https://school.programmers.co.kr/learn/courses/30/lessons/59411
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
OUTS.ANIMAL_ID,
OUTS.NAME
FROM ANIMAL_OUTS AS OUTS
LEFT JOIN ANIMAL_INS AS INS
ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
ORDER BY DATEDIFF(OUTS.DATETIME,INS.DATETIME) DESC
LIMIT 2;
7. 조건에 맞는 사용자 총 거래금액 조회하기
https://school.programmers.co.kr/learn/courses/30/lessons/164668
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
B.WRITER_ID AS USER_ID,
U.NICKNAME,
SUM(B.PRICE) AS TOTAL_SALES
FROM USED_GOODS_BOARD AS B
JOIN USED_GOODS_USER AS U
ON B.WRITER_ID = U.USER_ID
WHERE STATUS = 'DONE'
GROUP BY B.WRITER_ID, U.NICKNAME
HAVING SUM(B.PRICE) >= 700000
ORDER BY TOTAL_SALES;
SQL에서 집계 함수(SUM, COUNT, AVG 등)를 사용할 때는,
SELECT에 있는 모든 집계 함수가 아닌 컬럼들은 반드시 GROUP BY에 포함되어야 합니다.
8. 즐겨찾기가 가장 많은 식당 정보 출력하기
https://school.programmers.co.kr/learn/courses/30/lessons/131123
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
FOOD_TYPE,
REST_ID,
REST_NAME,
FAVORITES
FROM REST_INFO
WHERE (FOOD_TYPE, FAVORITES) IN
(SELECT FOOD_TYPE, MAX(FAVORITES) AS FAVORITES
FROM REST_INFO
GROUP BY FOOD_TYPE)
ORDER BY FOOD_TYPE DESC;
POINT!
서브쿼리로 FOOD_TYPE별 MAX(FAVORITES)만 뽑고,
그 값을 이용해 원래 테이블에서 정확히 일치하는 행을 찾기!
위에 문제와 이번 문제를 통해서 확실히 알고 가야할 개념!
✅ 1. GROUP BY에 포함된 컬럼 + 집계 함수만 SELECT에서 쓸 수 있어요
SELECT
컬럼A,
COUNT(*)
FROM 테이블
GROUP BY 컬럼A;
→ (컬럼A는 GROUP BY 대상이므로 가능)
❌ 아래처럼 하면 오류 나요 (표준 SQL 기준)
SELECT
컬럼A,
컬럼B,
COUNT(*)
FROM 테이블
GROUP BY 컬럼A;
→ 컬럼B는 그룹화 기준이 아닌데 SELECT에서 사용됨 → 오류 또는 비정확한 값
✅ 2. 집계되지 않은 컬럼도 SELECT에서 보고 싶다면?
SELECT
컬럼A,
컬럼B,
COUNT(*)
FROM 테이블
GROUP BY 컬럼A, 컬럼B;
→ 이 경우에는 컬럼A + 컬럼B 조합별로 그룹핑
9. 부서별 평균 연봉 조회하기
https://school.programmers.co.kr/learn/courses/30/lessons/284529
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
EM.DEPT_ID,
DE.DEPT_NAME_EN,
ROUND(AVG(EM.SAL), 0) AS AVG_SAL
FROM HR_EMPLOYEES AS EM
LEFT JOIN HR_DEPARTMENT AS DE
ON EM.DEPT_ID = DE.DEPT_ID
GROUP BY EM.DEPT_ID, DE.DEPT_NAME_EN
ORDER BY AVG_SAL DESC;
10. 조건에 맞는 사용자 정보 조회하기
https://school.programmers.co.kr/learn/courses/30/lessons/164670
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
SELECT
B.WRITER_ID AS USER_ID,
U.NICKNAME,
CONCAT(U.CITY,' ',
U.STREET_ADDRESS1,' ',
U.STREET_ADDRESS2) AS `전체주소`,
CONCAT(
SUBSTRING(U.TLNO, 1, 3),'-',
SUBSTRING(U.TLNO, 4, 4),'-',
SUBSTRING(U.TLNO, 8, 4)
) AS `전화번호`
FROM USED_GOODS_BOARD AS B
LEFT JOIN USED_GOODS_USER AS U
ON B.WRITER_ID = U.USER_ID
GROUP BY
B.WRITER_ID,
U.NICKNAME,
U.CITY,
U.STREET_ADDRESS1,
U.STREET_ADDRESS2,
U.TLNO
HAVING COUNT(B.WRITER_ID) >= 3
ORDER BY USER_ID DESC;
POINT!
문자열 처리 함수
| LEFT(str, N) | 왼쪽에서 N글자 추출 | LEFT('abcdef', 3) | 'abc' |
| RIGHT(str, N) | 오른쪽에서 N글자 추출 | RIGHT('abcdef', 3) | 'def' |
| SUBSTRING(str, start, len) 또는 SUBSTR() | 시작 위치부터 len만큼 추출 | SUBSTRING('abcdef', 2, 3) | 'bcd' |
| MID(str, start, len) | SUBSTRING()과 동일한 기능 | MID('abcdef', 2, 3) | 'bcd' |
| LPAD(str, total_len, pad_str) | 왼쪽에 pad_str를 채워서 길이 맞춤 | LPAD('123', 5, '0') | '00123' |
| RPAD(str, total_len, pad_str) | 오른쪽에 pad_str를 채워서 길이 맞춤 | RPAD('abc', 5, '*') | 'abc**' |
| LOCATE(substr, str) | 문자열 내 특정 부분의 위치 반환 | LOCATE('강', '서울 강남구') | 4 |
| INSTR(str, substr) | LOCATE와 동일 (순서만 반대) | INSTR('서울 강남구', '강') | 4 |
| SUBSTRING_INDEX(str, delim, count) | 구분자로 나눠서 앞/뒤 N번째 추출 | SUBSTRING_INDEX('a-b-c', '-', 2) | 'a-b' |
| CONCAT(str1, str2, ...) | 문자열 연결 | CONCAT('010', '-', '1234', '-', '5678') | '010-1234-5678' |
'코딩 테스트 > 02. SQL' 카테고리의 다른 글
| [프로그래머스]SQL 쿼리테스트 Lv3(3) (6) | 2025.07.30 |
|---|---|
| [프로그래머스] SQL 쿼리테스트 Lv3(2) (2) | 2025.07.29 |
| [윈도우 함수]- 순위(RANK) 함수 (0) | 2025.07.17 |
| [프로그래머스] SQL 쿼리테스트 Lv2(5) (3) | 2025.07.17 |
| [프로그래머스]SQL 쿼리 테스트 Lv2(4) (7) | 2025.07.16 |
