순서는 제가 풀이한 순서대로 정리해놨습니다 :) 문제 순서가 뒤죽박죽이라 제목 ctrl+f 해서 찾으시면 될것 같아요
업데이트 되기 전 문제들은 아래 게시글을 확인하시면 될 것 같습니다!
- 모든 레코드 조회하기
- 역순 정렬하기
- 아픈 동물 찾기
- 어린 동물 찾기
- 동물의 아이디와 이름
- 여러 기준으로 정렬하기
- 상위N개 레코드
2021.05.21 - [프로그래머스/SQL] - [프로그래머스 SQL] MySQL - SELECT 정답
1. 과일로 만든 아이스크림 고르기
필요 개념
- JOIN ... ON ...
- 두개의 테이블의 공통적인 것 기준으로 묶기
정답 코드
-- 코드를 입력하세요
SELECT A.FLAVOR
FROM FIRST_HALF A
JOIN ICECREAM_INFO B ON A.FLAVOR = B.FLAVOR
WHERE A.TOTAL_ORDER > 3000 AND B.INGREDIENT_TYPE = 'fruit_based'
ORDER BY A.TOTAL_ORDER DESC
2. 12세 이하인 여자 환자 목록 출력하기
필요 개념
- IFNULL(Column, "NULL일 경우 대체값") : Column의 값이 NULL을 반환할 때, 다른 값으로 출력할 수 있도록 하는 함수
SELECT IFNULL(COLUMN명, "NULL일경우 대체값") FROM 테이블명;
- ORDER BY
- ASC (기본값) : 오름차순
- DESC : 내림차순
- 여러개 기준 정렬가능
-- 나이순으로 내림차순 후 나이가 같은 경우 이름 오름차순
SELECT NAME, AGE FROM PATIENT
ORDER BY AGE DESC, NAME
정답 코드
-- 코드를 입력하세요
SELECT PT_NAME, PT_NO, GEND_CD, AGE, IFNULL(TLNO, 'NONE') AS TLNO
FROM PATIENT
WHERE GEND_CD = 'W' AND AGE <= 12
ORDER BY AGE DESC, PT_NAME
3. 흉부외과 또는 일반외과 의사 목록 출력하기
필요 개념
- DATE_FORMAT(날짜, '원하는 날짜 형식')
-- YYYY/mm/dd
--2020/04/05
SELECT DATE_FORMAT('20200405', '%Y/%m/%d')
-- YYYY-mm-dd
-- 2020-04-05
SELECT DATE_FORMAT('20200405', '%Y-%m-%d')
지정값 | 구분 | 표시 형식 |
%Y | 연 | 4자리 연도 (1900-2xxx) |
%y | 연 | 2자리 연도 (00-99) |
%m | 월 | 2자리(00-12) |
%c | 월 | 1자리, 10보다 작을경우 (1-12) |
%M | 월 | 이름(January, February...) |
%b | 월 | 줄인 이름(Jan, Feb...) |
%d | 일 | 2자리 (00-31) |
%D | 일 | 1st, 2nd |
%h | 시 | 12시간 형식 (01-12) |
%H | 시 | 24시간 형식(00-23) |
%i | 분 | 2자리 (00-59) |
%s | 초 | 2자리 (00-59) |
정답 코드
-- 코드를 입력하세요
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
4. 3월에 태어난 여성 회원 목록 출력하기
필요개념
- DATE_FORMAT이 많이 쓰이네요!
- IS NULL, IS NOT NULL
- WHERE절과 함께 쓰입니다
- 조건에 NULL인 값을 포함시키고 싶지 않다면 IS NOT NULL로 표현합니다
정답 코드
-- 코드를 입력하세요
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, '%m') = '03'
AND GENDER = 'W'
AND TLNO IS NOT NULL
ORDER BY MEMBER_ID ASC
5. 강원도에 위치한 생산공장 목록 출력하기
필요 개념
- WHERE ... LIKE ...
- 특정 문자로 시작하는 데이터 검색
- 특정 문자로 끝나는 데이터 검색
- 특정 문자를 포함하는 데이터 검색
- 복수개의 특정 문자를 포함하는 데이터 검색
--특정 문자로 시작하는 데이터 검색
SELECT [필드명] FROM [테이블명]
WHERE [필드명] LIKE '특정 문자열%';
--특정 문자로 끝나는 데이터 검색
SELECT [필드명] FROM [테이블명]
WHERE [필드명] LIKE '%특정 문자열';
--특정 문자를 포함하는 데이터 검색
SELECT [필드명] FROM [테이블명]
WHERE [필드명] LIKE '%특정 문자열%';
--복수개의 특정 문자를 포함하는 데이터 검색
--복수개의 특정 문자를 포함하는 데이터를 검색하기 위해서 OR연산자를 사용해야한다.
SELECT [필드명] FROM [테이블명]
WHERE [필드명] LIKE '%특정 문자열%' OR [필드명] LIKE '%특정 문자열2%';
정답 코드
-- 코드를 입력하세요
SELECT FACTORY_ID, FACTORY_NAME, ADDRESS
FROM FOOD_FACTORY
WHERE ADDRESS LIKE '강원도%'
ORDER BY FACTORY_ID ASC
6. 조건에 맞는 회원수 구하기
필요 개념
- 위에서 설명했던 DATE_FORMAT을 응용하면 됩니다
정답코드
-- 코드를 입력하세요
SELECT COUNT(USER_ID) AS USERS
FROM USER_INFO
WHERE AGE >= 20 AND AGE < 30 AND DATE_FORMAT(JOINED, '%Y') = '2021'
7. 재구매가 일어난 상품과 회원 리스트 구하기
필요 개념
- GROUP BY ... HAVING
- 유형별로 개수를 알고 싶을 때 사용한다
- 2가지 기억하기
- 특정 컬럼을 그룹화 하는 GROUP BY
- 특정 컬럼을 그룹화한 결과에 조건을 거는 HAVING
- WHERE과 HAVING 헷갈리지 않기. WHERE는 그룹화 하기 전이고, HAVING은 그룹화 후 조건
GROUP BY 예시
해당 게시글을 참고하였습니다
idx | type | name |
1 | 1 | 박다솔 |
2 | 1 | 김미미 |
3 | 2 | 이정훈 |
4 | 2 | 박민우 |
5 | 3 | 이건호 |
6 | 3 | 박유진 |
7 | 4 | 정다미 |
type 그룹화 하여 name개수 조회
SELECT type, COUNT(name) AS cnt FROM hero_collection GROUP BY type;
결과
type | cnt |
1 | 2 |
2 | 2 |
3 | 2 |
4 | 1 |
type 1초과인 type그룹화 하여 name개수를 가져온 후 그 중에 개수가 2개 이상인 데이터 조회
(조건 처리 후 컬럼 그룹화 후에 조건처리)
SELECT type, COUNT(name) AS cnt FROM hero_collection WHERE type > 1 GROUP BY type HAVING cnt >= 2;
결과
type | cnt |
2 | 2 |
3 | 2 |
정답 코드
-- 코드를 입력하세요
SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) >= 2
ORDER BY USER_ID, PRODUCT_ID DESC
8. 서울에 위치한 식당 목록 출력하기
필요 개념
- ROUND(num, 반올림할 자리)
- 소수점을 반올림
- AVG
- 평균값 구하기
- JOIN ... ON ...
- 두개의 테이블의 공통적인 것 기준으로 묶기
정답 코드
-- 코드를 입력하세요
SELECT
B.REST_ID AS REST_ID,
B.REST_NAME AS REST_NAME,
B.FOOD_TYPE AS FOOD_TYPE,
B.FAVORITES AS FAVORITES,
B.ADDRESS AS ADDRESS,
ROUND(AVG(A.REVIEW_SCORE), 2) AS SCORE
FROM REST_REVIEW A
JOIN REST_INFO B ON A.REST_ID = B.REST_ID
GROUP BY A.REST_ID
HAVING ADDRESS LIKE '서울%'
ORDER BY SCORE DESC, FAVORITES DESC
9. 인기있는 아이스크림
필요 개념
- order by
정답 코드
SELECT FLAVOR
FROM FIRST_HALF
ORDER BY TOTAL_ORDER DESC, SHIPMENT_ID
10. 오프라인/온라인 판매 데이터 통합하기
SELECT문제 중 저는 이 문제가 제일 어려웠습니다 ㅠㅠ
필요 개념
- UNION
- https://jmkim.tistory.com/50 해당 블로그를 통해 UNION과 UNION ALL에 대한 차이를 이해했습니다
- 간략하게 설명하면 UNION (DISTINCT)는 중복된 ROW는 제거합니다
- UNION ALL 은 중복된 값도 모두 보여줍니다
- NULL AS USER_ID
- UNION시 OFFLINE_SALE에는 USER_ID가 없기 때문에 NULL을 USER_ID로 표현하였다
정답 코드
SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE
, PRODUCT_ID
, USER_ID
, SALES_AMOUNT
FROM ONLINE_SALE
WHERE DATE_FORMAT(SALES_DATE, '%Y-%m-%d') LIKE '2022-03%'
UNION ALL
SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE
, PRODUCT_ID
, NULL AS USER_ID
, SALES_AMOUNT
FROM OFFLINE_SALE
WHERE DATE_FORMAT(SALES_DATE, '%Y-%m-%d') LIKE '2022-03%'
ORDER BY SALES_DATE, PRODUCT_ID, USER_ID