이번 포스팅에서는
프로그래머스 SQL Lv.1 문제 중 문자열 패턴 비교 연산자인 LIKE와 와일드카드 %를 이용한 문자열 필터링,
비교 연산자 BETWEEN, 날짜 함수 DATE_FORMAT()을 이용한 날짜 형식 지정,
집계 함수(MAX, AVG)를 수치형 함수(ROUND)로 후처리하는 문제를 함께 풀어본다.
📘 포함된 문제 목록
가장 비싼 상품 구하기
PRODUCT 테이블에서 판매 중인 상품 중 가장 높은 판매가를 출력하는 SQL문을 작성. 컬럼명은 MAX_PRICE로 지정.
테이블 예시
| PRODUCT_ID | PRODUCT_CODE | PRICE |
| 1 | A1000001 | 10000 |
| 2 | A2000005 | 9000 |
| 3 | C1000006 | 22000 |
SELECT MAX(PRICE) AS MAX_PRICE
FROM PRODUCT;
강원도에 위치한 생산공장 목록 출력하기
FOOD_FACTORY 테이블에서 강원도에 위치한 식품공장의 공장 ID, 공장 이름, 주소를 조회하는 SQL문을 작성. 결과는 공장 ID를 기준으로 오름차순 정렬.
테이블 예시
| FACTORY_ID | FACTORY_NAME | ADDRESS | TLNO |
| FT19980003 | (주)맛있는라면 | 강원도 정선군 남면 칠현로 679 | 033-431-3122 |
| FT19980004 | (주)맛있는기름 | 경기도 평택시 포승읍 포승공단순환로 245 | 031-651-2410 |
| FT20010001 | (주)맛있는소스 | 경상북도 구미시 1공단로7길 58-11 | 054-231-2121 |
| FT20010002 | (주)맛있는통조림 | 전라남도 영암군 미암면 곤미현로 1336 | 061-341-5210 |
| FT20100001 | (주)맛있는차 | 전라남도 장성군 서삼면 장산리 233-1번지 | 061-661-1420 |
| FT20100002 | (주)맛있는김치 | 충청남도 아산시 탕정면 탕정면로 485 | 041-241-5421 |
| FT20100003 | (주)맛있는음료 | 강원도 원주시 문막읍 문막공단길 154 | 033-232-7630 |
| FT20100004 | (주)맛있는국 | 강원도 평창군 봉평면 진조길 227-35 | 033-323-6640 |
| FT20110001 | (주)맛있는밥 | 경기도 화성시 팔탄면 가재리 34번지 | 031-661-1532 |
| FT20110002 | (주)맛있는과자 | 광주광역시 북구 하서로 222 | 062-211-7759 |
SELECT
FACTORY_ID,
FACTORY_NAME,
ADDRESS
FROM FOOD_FACTORY
WHERE ADDRESS LIKE '강원도%'
ORDER BY FACTORY_ID ASC;
🔍 포인트: 강원도에 위치한 → 주소가 강원도로 시작하는 → WHERE ADDRESS LIKE '강원도%'
%는 0자 이상 임의의 문자열을 대체하는 와일드카드
경기도에 위치한 식품창고 목록 출력하기
FOOD_WAREHOUSE 테이블에서 경기도에 위치한 창고의 ID, 이름, 주소, 냉동시설 여부를 조회하는 SQL문을 작성. 냉동시설 여부가 NULL인 경우, 'N'으로 출력시켜 주시고 결과는 창고 ID를 기준으로 오름차순 정렬.
테이블 예시
| WAREHOUSE_ID | WAREHOUSE_NAME | ADDRESS | TLNO | FREEZER_YN |
| WH0001 | 창고_경기1 | 경기도 안산시 상록구 용담로 141 | 031-152-1332 | Y |
| WH0002 | 창고_충북1 | 충청북도 진천군 진천읍 씨제이로 110 | 043-623-9900 | Y |
| WH0003 | 창고_경기2 | 경기도 이천시 마장면 덕평로 811 | 031-221-7241 | NULL |
| WH0004 | 창고_경기3 | 경기도 김포시 대곶면 율생중앙로205번길 | 031-671-1900 | N |
| WH0005 | 창고_충남1 | 충청남도 천안시 동남구 광덕면 신덕리1길 9 | 041-876-5421 | Y |
SELECT
WAREHOUSE_ID,
WAREHOUSE_NAME,
ADDRESS,
IFNULL(FREEZER_YN, 'N') AS FREEZER_YN
FROM FOOD_WAREHOUSE
WHERE ADDRESS LIKE '경기도%'
ORDER BY WAREHOUSE_ID;
🔍 포인트: 냉동시설 여부가 NULL인 경우, 'N'으로 출력 → IFNULL(FREEZER_YN, 'N') AS FREEZER_YN
COALESCE(FREEZER_YN, 'N') AS FREEZER_YN도 동일한 결과
COALESCE() 함수와 IFNULL() 함수 비교
| 항목 | COALESCE() | IFNULL() |
| 표준 여부 | SQL 표준 함수 | MySQL 전용 함수 (비표준) |
| 인자 개수 | 2개 이상 가능 (COALESCE(expr1, expr2, expr3, …)) | 2개만 가능 (IFNULL(expr1, expr2)) |
| 동작 방식 | 왼쪽부터 NULL이 아닌 첫 번째 값 반환 | 첫 번째 인자가 NULL이면 두 번째 값 반환 |
조건에 맞는 회원수 구하기
USER_INFO 테이블에서 2021년에 가입한 회원 중 나이가 20세 이상 29세 이하인 회원이 몇 명인지 출력하는 SQL문을 작성.
테이블 예시
| USER_ID | GENDER | AGE | JOINED |
| 1 | 1 | 26 | 2021-10-05 |
| 2 | 0 | NULL | 2021-11-25 |
| 3 | 1 | 22 | 2021-11-30 |
| 4 | 0 | 31 | 2021-12-03 |
| 5 | 0 | 28 | 2021-12-16 |
| 6 | 1 | 24 | 2022-01-03 |
| 7 | 1 | NULL | 2022-01-09 |
SELECT
COUNT(*) AS USERS
FROM USER_INFO
WHERE JOINED LIKE '2021%' AND AGE>=20 AND AGE<=29;
🔍 포인트: 2021년에 가입한 → JOINED가 2021로 시작하는 → JOINED LIKE '2021%'
나이가 20세 이상 29세 이하인 → AGE>=20 AND AGE<=29 또는 AGE BETWEEN 20 AND 29
흉부외과 또는 일반외과 의사 목록 출력하기
DOCTOR 테이블에서 진료과가 흉부외과(CS)이거나 일반외과(GS)인 의사의 이름, 의사ID, 진료과, 고용일자를 조회하는 SQL문을 작성. 결과는 고용일자를 기준으로 내림차순 정렬하고, 고용일자가 같다면 이름을 기준으로 오름차순 정렬.
테이블 예시
| DR_NAME | DR_ID | LCNS_NO | HIRE_YMD | MCDP_CD | TLNO |
| 루피 | DR20090029 | LC00010001 | 2009-03-01 | CS | 01085482011 |
| 패티 | DR20090001 | LC00010901 | 2009-07-01 | CS | 01085220122 |
| 뽀로로 | DR20170123 | LC00091201 | 2017-03-01 | GS | 01034969210 |
| 티거 | DR20100011 | LC00011201 | 2010-03-01 | NP | 01034229818 |
| 품바 | DR20090231 | LC00011302 | 2015-11-01 | OS | 01049840278 |
| 티몬 | DR20090112 | LC00011162 | 2010-03-01 | FM | 01094622190 |
| 니모 | DR20200012 | LC00911162 | 2020-03-01 | CS | 01089483921 |
| 오로라 | DR20100031 | LC00010327 | 2010-11-01 | OS | 01098428957 |
| 자스민 | DR20100032 | LC00010192 | 2010-03-01 | GS | 01023981922 |
| 벨 | DR20100039 | LC00010562 | 2010-07-01 | GS | 01058390758 |
SELECT
DR_NAME,
DR_ID,
MCDP_CD,
DATE_FORMAT(HIRE_YMD,'%Y-%m-%d') AS HIRE_YMD
FROM DOCTOR
WHERE MCDP_CD='CS' OR MCDP_CD='GS'
ORDER BY HIRE_YMD DESC, DR_NAME ASC;
🔍 포인트: DATE 타입의 데이터는 출력 시 내부적으로 DATETIME 형태(YYYY-MM-DD HH:MM:SS)로 표시될 수 있으므로,
순수한 날짜만 출력하려면 형식을 지정(DATE_FORMAT() 등 사용) 해야 한다.
인기있는 아이스크림
상반기에 판매된 아이스크림의 맛을 총주문량을 기준으로 내림차순 정렬하고 총주문량이 같다면 출하 번호를 기준으로 오름차순 정렬하여 조회하는 SQL 문을 작성.
테이블 예시
| SHIPMENT_ID | FLAVOR | TOTAL_ORDER |
| 101 | chocolate | 3200 |
| 102 | vanilla | 2800 |
| 103 | mint_chocolate | 1700 |
| 104 | caramel | 2600 |
| 105 | white_chocolate | 3100 |
| 106 | peach | 2450 |
| 107 | watermelon | 2150 |
| 108 | mango | 2900 |
| 109 | strawberry | 3100 |
| 110 | melon | 3150 |
| 111 | orange | 2900 |
| 112 | pineapple | 2900 |
SELECT
FLAVOR
FROM FIRST_HALF
ORDER BY TOTAL_ORDER DESC, SHIPMENT_ID ASC;
비전공자 빅분기 10회 필기 실기 1트 합격후기 (기출문제 복기)
나이 정보가 없는 회원 수 구하기
USER_INFO 테이블에서 나이 정보가 없는 회원이 몇 명인지 출력하는 SQL문을 작성. 컬럼명은 USERS로 지정.
테이블 예시
| USER_ID | GENDER | AGE | JOINED |
| 1 | 1 | 26 | 2021-06-01 |
| 2 | NULL | NULL | 2021-07-25 |
| 3 | 1 | NULL | 2021-07-30 |
| 4 | 0 | 31 | 2021-08-03 |
SELECT
COUNT(*) AS USERS
FROM USER_INFO
WHERE AGE IS NULL;
12세 이하인 여자 환자 목록 출력하기
PATIENT 테이블에서 12세 이하인 여자환자의 환자이름, 환자번호, 성별코드, 나이, 전화번호를 조회하는 SQL문을 작성. 전화번호가 없는 경우, 'NONE'으로 출력하고 결과는 나이를 기준으로 내림차순 정렬, 나이 같다면 환자이름을 기준으로 오름차순 정렬.
테이블 예시
| PT_NO | PT_NAME | GEND_CD | AGE | TLNO |
| PT22000003 | 브라운 | M | 18 | 01031246641 |
| PT22000004 | 크롱 | M | 7 | NULL |
| PT22000006 | 뽀뽀 | W | 8 | NULL |
| PT22000009 | 한나 | W | 12 | 01032323117 |
| PT22000012 | 뿡뿡이 | M | 5 | NULL |
| PT22000013 | 크리스 | M | 30 | 01059341192 |
| PT22000014 | 토프 | W | 22 | 01039458213 |
| PT22000018 | 안나 | W | 11 | NULL |
| PT22000019 | 바라 | W | 10 | 01079068799 |
| PT22000021 | 릴로 | W | 33 | 01023290767 |
SELECT
PT_NAME,
PT_NO,
GEND_CD,
AGE,
COALESCE(TLNO, 'NONE') AS TLNO
FROM PATIENT
WHERE AGE<=12 AND GEND_CD='W'
ORDER BY AGE DESC, PT_NAME ASC;
🔍 포인트: 전화번호가 없는 경우, 'NONE'으로 출력 → COALESCE(TLNO, 'NONE') AS TLNO
IFNULL (TLNO, 'NONE') AS TLNO도 동일한 결과
조건에 맞는 도서 리스트 출력하기
BOOK 테이블에서 2021년에 출판된 '인문' 카테고리에 속하는 도서 리스트를 찾아서 도서 ID(BOOK_ID), 출판일 (PUBLISHED_DATE)을 출력하는 SQL문을 작성. 결과는 출판일을 기준으로 오름차순 정렬.
테이블 예시
| BOOK_ID | CATEGORY | AUTHOR_ID | PRICE | PUBLISHED_DATE |
| 1 | 인문 | 1 | 10000 | 2020-01-01 |
| 2 | 경제 | 2 | 9000 | 2021-02-05 |
| 3 | 인문 | 2 | 11000 | 2021-04-11 |
| 4 | 인문 | 3 | 10000 | 2021-03-15 |
| 5 | 생활 | 1 | 12000 | 2021-01-10 |
SELECT
BOOK_ID,
DATE_FORMAT(PUBLISHED_DATE,'%Y-%m-%d') AS PUBLISHED_DATE
FROM BOOK
WHERE PUBLISHED_DATE LIKE '2021%' AND CATEGORY='인문'
ORDER BY PUBLISHED_DATE ASC;
🔍 포인트: DATETIME 형태가 아닌 순수한 날짜만 출력하기 위해 DATE_FORMAT()을 사용하여 형식을 지정한다.
평균 일일 대여 요금 구하기
CAR_RENTAL_COMPANY_CAR 테이블에서 자동차 종류가 'SUV'인 자동차들의 평균 일일 대여 요금을 출력하는 SQL문을 작성. 평균 일일 대여 요금은 소수 첫 번째 자리에서 반올림하고, 컬럼명은 AVERAGE_FEE로 지정.
테이블 예시
| CAR_ID | CAR_TYPE | DAILY_FEE | OPTIONS |
| 1 | 세단 | 16000 | 가죽시트,열선시트,후방카메라 |
| 2 | SUV | 14000 | 스마트키,네비게이션,열선시트 |
| 3 | SUV | 22000 | 주차감지센서,후방카메라,가죽시트 |
SELECT
ROUND(AVG(DAILY_FEE)) AS AVERAGE_FEE
FROM CAR_RENTAL_COMPANY_CAR
WHERE CAR_TYPE='SUV';
🔍 포인트: 평균 일일 대여 요금 AVG(DAILY_FEE)을 소수 첫 번째 자리에서 반올림 → 정수로 반올림 → ROUND(AVG(DAILY_FEE)) 또는 ROUND(AVG(DAILY_FEE),0)






댓글