안녕하세요.
요즘 PCSQL 준비를 위해 부랴부랴 공부중인데요. . .
이번 글에서는 프로그래머스 SQL 고득점 Kit의 SELECT 문제를 풀면서,
제가 작성한 정답과 풀이 팁등을 정리하려고 합니다.
⚠️ 저의 정답이 항상 최고의 방법은 아닐 수 있습니다.
✨ 표시는 중요하다고 판단한 문제입니다.
✨ 조건에 부합하는 중고거래 댓글 조회하기
SELECT A.TITLE
, A.BOARD_ID
, B.REPLY_ID
, B.WRITER_ID
, B.CONTENTS
, DATE_FORMAT(B.CREATED_DATE, '%Y-%m-%d') AS CREATED_DATE
FROM USED_GOODS_BOARD AS A
INNER
JOIN USED_GOODS_REPLY AS B
ON A.BOARD_ID = B.BOARD_ID
-- 방법1. SUBSTR로 10월에 작성된 게시글 필터링
WHERE SUBSTR(A.CREATED_DATE, 1, 7) = '2022-10'
-- 방법2. BETWEEN AND로 10월에 작성된 게시글 필터링
# WHERE A.CREATED_DATE BETWEEN '2022-10-01' AND '2022-10-31'
-- 방법3. 연산자로 10월에 작성된 게시글 필터링
# WHERE A.CREATED_DATE >= '2022-10-01' AND A.CREATED_DATE <= '2022-11-01';
ORDER
BY B.CREATED_DATE ASC, A.TITLE ASC;
DATE_FORMAT
MySQL에서 DATE_FORMAT 함수는 날짜/시간 값을 원하는 형식으로 문자열로 변환할 때 사용합니다.
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');
위와 같은 형태로 쓰이며, 날짜와 시간의 출력 형식을 자유롭게 지정할 수 있습니다.
대문자와 소문자가 다르면 결과가 달라집니다. (%Y vs %y, %M vs %m 등)
포맷 문자 설명 예시 (2025-09-16)
| 포맷 문자 | 설명 | 예시 (2025-09-16) |
| %Y | 4자리 연도 | 2025 |
| %y | 2자리 연도 | 25 |
| %M | 월 이름 | September |
| %m | 2자리 월 | 09 |
| %c | 1~12월 | 9 |
| %D | 일 + 영어 접미사 | 16th |
| %d | 2자리 일 | 16 |
| %e | 1~31일 | 16 |
| %H | 24시간 | 17 |
| %h / %I | 12시간 | 05 |
| %i | 분 | 25 |
| %s / %S | 초 | 30 |
| %W | 요일 이름 | Tuesday |
| %a | 요일 약어 | Tue |
한줄 정리
- 연도: Y(2025), y(25)
- 월: M(September), m(09), c(9)
- 일: D(6th), d(6), e(6)
- 시: H(19), h/I(07)
- 분: i(32)
- 초: s/S(30)
- 요일: W(Tuesday)
- 요일 약어(Tue)
BETWEEN AND
범위 조건 조회에 사용됩니다.
이 문제에서는, 10월달에 발행된 글을 필터링할 때 다음과 같이 쓸 수 있습니다.
(BETWEEN AND는 경계값을 포함합니다.)
WHERE A.CREATED_DATE BETWEEN '2022-10-01' AND '2022-10-31'
/*
위의 문법은 아래와 완전히 동일합니다.
WHERE A.CREATED_DATE >= '2022-10-01' AND A.CREATED_DATE <= '2022-11-01';
*/
SUBSTR
문자열의 일부를 추출합니다.
# SUBSTR(string, start_index, length);
SELECT SUBSTR('2025-09-16', 1, 7); -- '2025-09'
✨ 과일로 만든 아이스크림 고르기
SELECT A.FLAVOR
FROM ICECREAM_INFO A
-- INNER JOIN은 JOIN과 동일하므로 INNER를 생략해도 무방
INNER
JOIN FIRST_HALF B
ON A.FLAVOR = B.FLAVOR
AND B.TOTAL_ORDER >= 3000
WHERE A.INGREDIENT_TYPE = 'fruit_based';
흉부외과 또는 일반외과 의사 목록 출력하기
SELECT DR_NAME
, DR_ID
, MCDP_CD
, DATE_FORMAT(HIRE_YMD, '%Y-%m-%d') AS HIRE_YMD
FROM DOCTOR
-- OR 조건으로 진료과 필터링
# WHERE MCDP_CD = 'CS' OR MCDP_CD = 'GS';
-- IN 조건으로 진료과 필터링
WHERE MCDP_CD IN ('CS', 'GS');ORDER BY HIRE_YMD DESC, DR_NAME ASC;
IN ('CS', 'GS')
IN 연산자는 여러 값 중 하나와 일치하는지 확인할 때 사용합니다.
위의 예제에서는 MCDP_CD가 'CS'이거나 'GS'인 컬럼만 필터링 해줍니다.
NUMBER IN (1, 3, 5, ...); -- 1, 3, 5인 값만 필터링
OR에 비해 쿼리가 간결하고 가독성이 좋아지는 장점이 있습니다.
NOT IN으로 부정 조건도 가능합니다.
12세 이하인 여자 환자 목록 출력하기
SELECT PT_NAME
, PT_NO
, GEND_CD
, AGE
, NVL(TLNO, 'NONE')
FROM PATIENT
WHERE AGE <= 12
AND GEND_CD = 'W'
ORDER BY AGE DESC, PT_NAME ASC;
인기있는 아이스크림
SELECT FLAVOR
FROM FIRST_HALF
ORDER BY TOTAL_ORDER DESC, SHIPMENT_ID ASC;
조건에 맞는 도서 리스트 출력하기
SELECT BOOK_ID
, DATE_FORMAT(PUBLISHED_DATE, '%Y-%m-%d') AS PUBLISHED_DATE
FROM BOOK
WHERE SUBSTR(PUBLISHED_DATE, 1, 4) = '2021'
AND CATEGORY = '인문'
ORDER BY PUBLISHED_DATE ASC;
✨ 평균 일일 대여 요금 구하기
SELECT ROUND(AVG(DAILY_FEE)) AS AVERAGE_FEE
FROM CAR_RENTAL_COMPANY_CAR
WHERE CAR_TYPE = 'SUV';
ROUND
숫자를 반올림하여 지정한 소수점 자리로 나타내는 함수입니다.
음수 자릿수도 지원합니다. (소숫점 왼쪽 자리에서 반올림)
# ROUND(number, [decimal_places])
SELECT ROUND(123.456, 2); -- 결과: 123.46
SELECT ROUND(123.456, 0); -- 결과: 123
SELECT ROUND(123.456, -1); -- 결과: 120
비슷한 함수로는 CEIL(CEILING)과 FLOOR가 있습니다.
- CEIL: 숫자를 올림하여 정수로 반환
- FLOOR: 숫자를 내림하여 정수로 반환
AVG
특정 컬럼의 평균값을 계산합니다.
# AVG(column_name)
숫자형 컬럼에만 적용 가능합니다.
NULL값은 자동으로 제외하고 계산합니다.
3월에 태어난 여성 회원 목록 출력하기
SELECT MEMBER_ID,
MEMBER_NAME,
GENDER,
DATE_FORMAT(DATE_OF_BIRTH, '%Y-%m-%d') AS DATE_OF_BIRTH
FROM MEMBER_PROFILE
WHERE DATE_FORMAT(DATE_OF_BIRTH, '%c') = '3' -- 생일이 3월인 회원
AND GENDER = 'W' -- 성별이 여성인 회원
AND TLNO IS NOT NULL -- TLNO 값이 존재하는 회원
ORDER BY MEMBER_ID ASC; -- 회원 ID 기준 오름차순 정렬
- DATE_FORMAT(DATE_OF_BIRTH, '%c') → 한 자리 숫자로 월(month) 표시
- IS NOT NULL → MySQL에서 NULL 값이 아닌지 체크
- != NULL 사용 ❌ → 항상 UNKNOWN
- IS NULL / IS NOT NULL ✅ → 올바른 문법
강원도에 위치한 생산공장 목록 출력하기
SELECT FACTORY_ID
, FACTORY_NAME
, ADDRESS
FROM FOOD_FACTORY
WHERE ADDRESS LIKE '강원도%'
ORDER BY FACTORY_ID ASC;
LIKE
LIKE는 문자열 패턴 검색에 사용하는 연산자입니다.
- % → 0개 이상의 문자
- _ → 정확히 1개의 문자
-- '홍'으로 시작하는 이름 조회
NAME LIKE '홍%';
-- '길동'으로 끝나는 이름 조회
NAME LIKE '%길동';
-- 이름이 두 글자이고 두 번째 글자가 '길'인 경우
NAME LIKE '_길';
서울에 위치한 식당 목록 출력하기
SELECT A.REST_ID,
A.REST_NAME,
A.FOOD_TYPE,
A.FAVORITES,
A.ADDRESS,
ROUND(AVG(B.REVIEW_SCORE), 2) AS AVERAGE
FROM REST_INFO A
JOIN REST_REVIEW B
ON A.REST_ID = B.REST_ID
WHERE A.ADDRESS LIKE '서울%'
GROUP BY A.REST_ID, A.REST_NAME, A.FOOD_TYPE, A.FAVORITES, A.ADDRESS
ORDER BY AVERAGE DESC, A.FAVORITES DESC;
GROUP BY와 집계함수는 필수는 아니다. 하지만 위와 같은 경우에서는 명지해주는 것이 좋다. 그렇지 않으면 MYSQL에서 FULL 오류가 발생할 수 있다.
