본문 바로가기
Data Analysis/Query

[MySQL] 프로그래머스 Lv.2

by 베짱이28호 2024. 1. 8.

[MySQL] 프로그래머스 Lv.2

  • [MySQL] 프로그래머스 Lv.2

문제

1. 동물의 수 구하기

코딩테스트 연습 - 동물 수 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT COUNT(*)
FROM ANIMAL_INS;

 

  • count로 개수 반환하기.
  • NULL 개수 카운트

2. 최솟값 구하기

코딩테스트 연습 - 최솟값 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT DATETIME AS 시간
FROM ANIMAL_INS
ORDER BY DATETIME
LIMIT 1;
  • 최대, 최소 : 정렬 후 LIMIT 1

3. 동명 동물 수 찾기

코딩테스트 연습 - 동명 동물 수 찾기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT NAME,COUNT(NAME)
FROM ANIMAL_INS
GROUP BY NAME
HAVING COUNT(NAME) > 1 # AND NAME IS NOT NULL
ORDER BY NAME;

SELECT NAME,COUNT(*)
FROM ANIMAL_INS
GROUP BY NAME
HAVING COUNT(*) > 1 AND NAME IS NOT NULL
ORDER BY NAME;
  • Name은 NULLABLE TRUE라서 집계에서 제외
  • 같은 이름별로 묶어서 몇 번 나왔는지 체크해야하므로 HAVING COUN
  • HAVING절에서 NAME 걸어주면 NULL값을 이미 걸러내므로 뒤에 AND는 사실 필요가 없다.

4. 중복 제거하기

코딩테스트 연습 - 중복 제거하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT COUNT(DISTINCT NAME)
FROM ANIMAL_INS
WHERE NAME IS NOT NULL;

SELECT COUNT(DISTINCT NAME)
FROM ANIMAL_INS;
  • 위 문제랑 비슷한 맥락으로 이미 NULL을 걸러주면 IS NOT NULL을 써줄 필요가 없다.

5. 이름에 el이 들어가는 동물 찾기

코딩테스트 연습 - 이름에 el이 들어가는 동물 찾기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT ANIMAL_ID,NAME
FROM ANIMAL_INS
WHERE UPPER(NAME) LIKE '%EL%' AND ANIMAL_TYPE = 'Dog'
ORDER BY NAME;
  • 대소문자 구분하지 않으니, UPPPER이든 LOWER든 하나로 통일한다.
  • %으로 나머지 부분을 치환한다 생각한다.

6. NULL 처리하기

코딩테스트 연습 - NULL 처리하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT ANIMAL_TYPE, COALESCE(NAME,'No name'), SEX_UPON_INTAKE
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;
  • COALESCE를 사용해서 가장 먼저 NULL이 아닌 값으로 대체한다.

7. DATETIME에서 DATE로 형 변환

코딩테스트 연습 - DATETIME에서 DATE로 형 변환 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT ANIMAL_ID, NAME, LEFT(DATETIME,10) AS 날짜
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;

SELECT ANIMAL_ID, NAME, DATE_FORMAT(DATETIME, '%Y-%m-%d') AS 날짜
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;
  • 위에 코드로 풀어도 되지만 가독성이 떨어진다.
  • DATE FORMAT을 사용해서 YYYY-MM-DD 포맷으로 바꿔준다.

8. 가격이 제일 비싼 식품의 정보 출력하기

코딩테스트 연습 - 가격이 제일 비싼 식품의 정보 출력하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT PRODUCT_ID, PRODUCT_NAME, PRODUCT_CD, CATEGORY, PRICE
FROM FOOD_PRODUCT
ORDER BY PRICE DESC
LIMIT 1;

SELECT *
FROM FOOD_PRODUCT
ORDER BY PRICE DESC
LIMIT 1;
  • 정렬 후 LIMIT 1
  • 이 문제에서는 요구하는 컬럼이 전체 컬럼이랑 같다.

9. 카테고리 별 상품 개수 구하기

코딩테스트 연습 - 카테고리 별 상품 개수 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT LEFT(PRODUCT_CODE,2), COUNT(*) AS PRODUCTS
FROM PRODUCT
GROUP BY LEFT(PRODUCT_CODE,2)
  • 상품코드 앞 두자리가 제품군을 나타낸다. LEFT로 추출하기
  • GROUOP BY로 추출했으면, COUNT로 개수를 세준다. NULL 상관 없으므로 COUNT(*)

10. 중성화 여부 파악하기

코딩테스트 연습 - 중성화 여부 파악하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT
    ANIMAL_ID,
    NAME,
    CASE
        WHEN SEX_UPON_INTAKE LIKE '%Neutered%' OR SEX_UPON_INTAKE LIKE '%Spayed%' THEN 'O'
        ELSE 'X'
    END AS 중성화
FROM ANIMAL_INS;

SELECT
    ANIMAL_ID,
    NAME,
    IF(SEX_UPON_INTAKE LIKE '%Neutered%' OR SEX_UPON_INTAKE LIKE '%Spayed%', 'O', 'X') AS 중성화
FROM ANIMAL_INS;
  • CASE WHEN으로 나누거나 IF문으로 나눠주기
  • IF는 엑셀처럼 조건문, TRUE값, FALSE값으로 반환한다.
  • CASE가 많지 않거나 T/F로 반환하는 간단한 조건문에선 IF를 사용하는게 가독성이 더 좋아보인다.

11. 고양이와 개는 몇 마리 있을까

코딩테스트 연습 - 고양이와 개는 몇 마리 있을까 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT ANIMAL_TYPE , COUNT(ANIMAL_TYPE) AS count
FROM ANIMAL_INS
GROUP BY ANIMAL_TYPE
HAVING ANIMAL_TYPE = 'Cat' or ANIMAL_TYPE = 'Dog'
ORDER BY ANIMAL_TYPE;

SELECT ANIMAL_TYPE, COUNT(ANIMAL_TYPE) AS count
FROM ANIMAL_INS
WHERE ANIMAL_TYPE IN ('Cat', 'Dog')
GROUP BY ANIMAL_TYPE
ORDER BY ANIMAL_TYPE;
  • ANIMAL TYPE에서 GROUP BY로 HAVING으로 고양이와 개만 조회해준다.
  • 각 쿼리를 COUNT해주어 반환한다.
  • 아래 쿼리처럼, WHERE로 조건에 맞는 쿼리만 불러오고 조회할 수 있다.
  • WHERE로 먼저 뽑고나서 GROUPBY를 해주는게 더 연산량이 적을 듯 하다.

 

12. 진료과별 총 예약 횟수 출력하기

코딩테스트 연습 - 진료과별 총 예약 횟수 출력하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT MCDP_CD AS 진료과코드, COUNT(*) AS 5월예약건수
FROM APPOINTMENT
WHERE MONTH(APNT_YMD) = 5
GROUP BY MCDP_CD
ORDER BY 5월예약건수,진료과코드
  • 5월 진료기록 중, 진료과 코드로 그루핑해주고 카운트 해주기.

13. 입양 시각 구하기(1)

코딩테스트 연습 - 입양 시각 구하기(1) | 프로그래머스 스쿨 (programmers.co.kr)

SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
FROM ANIMAL_OUTS
WHERE HOUR(DATETIME) BETWEEN 9 AND 19
GROUP BY HOUR(DATETIME)
ORDER BY HOUR;
  • 조건에 맞는 시간대를 가져오고, 그루핑 해주기.
  • COUNT로 시간에 따른 횟수 구하기

14. 자동차 종류 별 특정 옵션이 포함된 자동차 수 구하기

코딩테스트 연습 - 자동차 종류 별 특정 옵션이 포함된 자동차 수 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT CAR_TYPE, COUNT(*) AS CARS
FROM CAR_RENTAL_COMPANY_CAR
WHERE OPTIONS LIKE '%통풍시트%' OR OPTIONS LIKE '%열선시트%' OR OPTIONS LIKE '%가죽시트%'
GROUP BY CAR_TYPE
ORDER BY CAR_TYPE;
  • 시트 옵션 들어가있는 쿼리만 추려내고, 그루핑해서 숫자 세주기

15. 상품 별 오프라인 매출 구하기

코딩테스트 연습 - 상품 별 오프라인 매출 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT PRODUCT_CODE, SUM(P.PRICE * O.SALES_AMOUNT) AS SALES
FROM PRODUCT AS P
JOIN OFFLINE_SALE AS O ON P.PRODUCT_ID = O.PRODUCT_ID
GROUP BY PRODUCT_CODE
ORDER BY SALES DESC, PRODUCT_CODE;
  • 상품 별 매출액 합이고 두 테이블이 분리되어있다.
  • ID를 통해서 JOIN을 한 후, 상품 코드로 그루핑을 해주고 총 매출액은 판매가*판매량으로 굼한다.

16. 조건에 맞는 도서와 저자 리스트 출력하기

코딩테스트 연습 - 조건에 맞는 도서와 저자 리스트 출력하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT B.BOOK_ID, A.AUTHOR_NAME, DATE_FORMAT(B.PUBLISHED_DATE, '%Y-%m-%d') AS PUBLISHED_DATE
FROM BOOK AS B
JOIN AUTHOR AS A ON B.AUTHOR_ID = A.AUTHOR_ID
WHERE B.CATEGORY = '경제'
ORDER BY B.PUBLISHED_DATE;
  • 포매팅으로 날짜 포매팅 바꿔주기.
  • WHERE 조건에서 경제 OR 카테고리 코드로 접근을 해줘야한다.
  • 코드는 여러개로 나누어져있어서 카테고리에 직접 접근하는게 나을듯.

17. 성분으로 구분한 아이스크림 총 주문량

코딩테스트 연습 - 성분으로 구분한 아이스크림 총 주문량 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT II.INGREDIENT_TYPE, SUM(FH.TOTAL_ORDER) AS TOTAL_ORDER
FROM FIRST_HALF FH
JOIN ICECREAM_INFO II ON FH.FLAVOR = II.FLAVOR
GROUP BY II.INGREDIENT_TYPE
ORDER BY TOTAL_ORDER;
  • 맛으로 테이블을 조인해주고, 성분으로 그루핑을 해준다.
  • 총 주문량은 SUM으로 그룹별 합산 구해주기

18. 루시와 엘라 찾기

코딩테스트 연습 - 루시와 엘라 찾기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
WHERE NAME IN ('Lucy', 'Ella', 'Pickle', 'Rogan', 'Sabrina', 'Mitty')
ORDER BY ANIMAL_ID;
  • 일치하는 조건이 많을때는 해시를 이용해서 빠르게 찾기. 사실 파이썬서도 웬만큼 큰게 아니면 O(1)이 실제 O(1)이 아니라서 이런 케이스는 비슷할 듯 하다.

18. 3월에 태어난 여성 회원 목록 출력하기

코딩테스트 연습 - 3월에 태어난 여성 회원 목록 출력하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT MEMBER_ID, MEMBER_NAME, GENDER, DATE_FORMAT(DATE_OF_BIRTH,'%Y-%m-%d') AS DATE_OF_BIRTH
FROM MEMBER_PROFILE 
WHERE GENDER = 'W' AND MONTH(DATE_OF_BIRTH) = 3 AND TLNO IS NOT NULL
ORDER BY MEMBER_ID;
  • 단순 WHERE + ORDER BY

19. 가격대 별 상품 개수 구하기

코딩테스트 연습 - 가격대 별 상품 개수 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT (PRICE DIV 10000)*10000 AS PRICE_GROUP, COUNT(*) AS PRODUCTS
FROM PRODUCT
GROUP BY PRICE_GROUP
ORDER BY PRICE_GROUP;

SELECT TRUNCATE(PRICE,-4) AS PRICE_GROUP, COUNT(*) AS PRODUCTS
FROM PRODUCT
GROUP BY PRICE_GROUP
ORDER BY PRICE_GROUP;
  • 몫은 DIV, 나머지는 %. 몫을 구하고 다시 10000을 곱해서 그룹을 나눈다.
  • 밑에 풀이는 버림 사용해서 푼 풀이.
  • TRUNCATE에 -4는 일-십-백-천, 천의 자리에서 버림

20. 재구매가 일어난 상품과 회원 리스트 구하기

코딩테스트 연습 - 재구매가 일어난 상품과 회원 리스트 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT USER_ID, PRODUCT_ID 
FROM ONLINE_SALE 
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) > 1
ORDER BY USER_ID, PRODUCT_ID DESC
  • 다중 컬럼으로 그루핑하기.
  • 같은 유저가 같은 상품을 구매하고, COUNT가 1개보다 크면 재주문.

21. 조건에 부합하는 중고거래 상태 조회하기

코딩테스트 연습 - 조건에 부합하는 중고거래 상태 조회하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT BOARD_ID, WRITER_ID, TITLE, PRICE,
    CASE 
        WHEN STATUS = 'SALE' THEN '판매중'
        WHEN STATUS = 'RESERVED' THEN '예약중'
        WHEN STATUS = 'DONE' THEN '거래완료'
    END AS STATUS
FROM USED_GOODS_BOARD
WHERE DATE(CREATED_DATE) = '2022-10-05'
ORDER BY BOARD_ID DESC;
  • CASE WHEN구문. WHEN 계속 적어주는거 너무 짜침

22. 자동차 평균 대여 기간 구하기

코딩테스트 연습 - 자동차 평균 대여 기간 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT CAR_ID, ROUND(AVG(DATEDIFF(END_DATE, START_DATE)+1), 1) AS AVERAGE_DURATION
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
HAVING AVERAGE_DURATION >= 7
ORDER BY AVERAGE_DURATION DESC, CAR_ID DESC;

 

  • 파생컬럼 추출하기
  • CAR_ID별로 해야하니 먼저 묶어주고, DATEDIFF를 통해서 평균 대여기간을 구한다.
  • 주의점은 같은날에 반납해도 1일 빌리는 경우이므로 +1 해주기.

23. 조건에 맞는 아이템들의 가격의 총합 구하기

코딩테스트 연습 - 조건에 맞는 아이템들의 가격의 총합 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT SUM(PRICE) AS TOTAL_PRICE
FROM ITEM_INFO
WHERE RARITY = 'LEGEND'
  • 그냥 WHERE + 집계함수

24. ROOT 아이템 구하기

코딩테스트 연습 - ROOT 아이템 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT T.ITEM_ID, I.ITEM_NAME
FROM ITEM_TREE AS T
JOIN ITEM_INFO AS I ON I.ITEM_ID = T.ITEM_ID
WHERE T.PARENT_ITEM_ID IS NULL
  • JOIN해서 특정 컬럼의 NULL 조건 걸어주기.

25. 연도 별 평균 미세먼지 농도 조회하기

코딩테스트 연습 - 연도 별 평균 미세먼지 농도 조회하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT YEAR(YM) AS YEAR, ROUND(AVG(PM_VAL1), 2) AS PM10, ROUND(AVG(PM_VAL2), 2) AS 'PM2.5'
FROM AIR_POLLUTION
WHERE LOCATION2 = '수원'
GROUP BY YEAR(YM)
ORDER BY YEAR(YM);
  • PM2.5에서 .5때문에 따옴표나 큰따옴표로 묶기
  • 나머지는 년도별로 GROUP BY

26. 노션별 평균 역 사이 거리 조회하기

코딩테스트 연습 - 노선별 평균 역 사이 거리 조회하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT ROUTE,
    CONCAT(ROUND(SUM(D_BETWEEN_DIST),1),'km') AS TOTAL_DISTANCE, 
    CONCAT(ROUND(AVG(D_BETWEEN_DIST),2),'km') AS AVERAGE_DISTANCE
FROM SUBWAY_DISTANCE
GROUP BY ROUTE
ORDER BY ROUND(SUM(D_BETWEEN_DIST),1) DESC;
  • TOTAL_DISTANCE로 정렬해버리면 문자열 비교이다.
  • 숫자 6KM처럼 숫자 소수점 자리가 없어진 경우에는, 숫자가 아니라 숫자와 문자를 비교할 수 있어서 TOTAL_DISTTANCE 컬럼 대신 안에 있는 ROUND SUM을 기준으로 한다.

27. 조건에 맞는 개발자 찾기

코딩테스트 연습 - 조건에 맞는 개발자 찾기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT D.ID, D.EMAIL, D.FIRST_NAME, D.LAST_NAME
FROM DEVELOPERS AS D
WHERE EXISTS (
    SELECT 1 
    FROM SKILLCODES AS S
    WHERE (D.SKILL_CODE & S.CODE) AND S.NAME IN ('Python', 'C#')
)
ORDER BY ID;
  • 비트 마스킹해서 풀이
  • CODE의 비트값은 어떤 특정 한 자리만 1인 상태
  • 이 CODE와 SKILL CODE를 비트연산하면 CODE에서 1이 들어온 자리수 말고는 의미가 없다.
  • CODE가 1인 자리에서 & 비트연산 값이 1이면 언어 사용할줄 아는거고, 아닌 경우 사용 불가이다.

28. 조건에 맞는 사원 정보 조회하기

코딩테스트 연습 - 조건에 맞는 사원 정보 조회하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT SUM(G.SCORE) AS SCORE, E.EMP_NO, E.EMP_NAME, E.POSITION, E.EMAIL
FROM HR_EMPLOYEES AS E
JOIN HR_GRADE AS G ON G.EMP_NO = E.EMP_NO
WHERE G.YEAR = 2022
GROUP BY E.EMP_NO
ORDER BY SCORE DESC
LIMIT 1;
  • DEPARTMENT 정보는 왜 준건지...... 마지막에 소속 부서라도 넣어놓든가
  • JOIN해주고, 상반기 하반기 정보를 묶어야 되니 사원번호 EMP_NO로 GRUOP BY

29. 업그레이드 된 아이템 구하기

코딩테스트 연습 - 업그레이드 된 아이템 구하기 | 프로그래머스 스쿨 (programmers.co.kr)

SELECT I.ITEM_ID, I.ITEM_NAME, I.RARITY
FROM ITEM_INFO AS I
JOIN ITEM_TREE AS T ON I.ITEM_ID = T.ITEM_ID
WHERE T.PARENT_ITEM_ID IN (SELECT ITEM_ID FROM ITEM_INFO WHERE RARITY = 'RARE')
ORDER BY 1 DESC;
  • 부모가 있는 아이템이 레어 아이템에 조회가 되면 된다.

댓글