프로그래머스 SQL Lv.4 ~ 5 문제 풀이

seo0·2024년 6월 19일

SQL

목록 보기
5/8
post-thumbnail

Lv.4


SELECT



서울에 위치한 식당 목록 출력하기

REST_INFO와 REST_REVIEW 테이블에서 서울에 위치한 식당들의 식당 ID, 식당 이름, 음식 종류, 즐겨찾기수, 주소, 리뷰 평균 점수를 조회하는 SQL문을 작성해주세요. 이때 리뷰 평균점수는 소수점 세 번째 자리에서 반올림 해주시고 결과는 평균점수를 기준으로 내림차순 정렬해주시고, 평균점수가 같다면 즐겨찾기수를 기준으로 내림차순 정렬해주세요.

   SELECT A.REST_ID
        , A.REST_NAME
        , A.FOOD_TYPE
        , A.FAVORITES
        , A.ADDRESS
        , ROUND(AVG(B.REVIEW_SCORE), 2) AS SCORE
     FROM REST_INFO A
LEFT JOIN REST_REVIEW B
       ON A.REST_ID = B.REST_ID
    WHERE A.ADDRESS LIKE '서울%' AND B.REVIEW_SCORE IS NOT NULL
 GROUP BY A.REST_ID
 ORDER BY SCORE DESC
        , A.FAVORITES DESC

오프라인/온라인 판매 데이터 통합하기

ONLINE_SALE 테이블과 OFFLINE_SALE 테이블에서 2022년 3월의 오프라인/온라인 상품 판매 데이터의 판매 날짜, 상품ID, 유저ID, 판매량을 출력하는 SQL문을 작성해주세요. OFFLINE_SALE 테이블의 판매 데이터의 USER_ID 값은 NULL 로 표시해주세요. 결과는 판매일을 기준으로 오름차순 정렬해주시고 판매일이 같다면 상품 ID를 기준으로 오름차순, 상품ID까지 같다면 유저 ID를 기준으로 오름차순 정렬해주세요.

   SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE
        , PRODUCT_ID
        , USER_ID
        , SALES_AMOUNT
     FROM ONLINE_SALE
    WHERE SALES_DATE LIKE '2022-03%'
UNION ALL
   SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE
        , PRODUCT_ID
        , NULL
        , SALES_AMOUNT
     FROM OFFLINE_SALE
    WHERE SALES_DATE LIKE '2022-03%'
 ORDER BY SALES_DATE
        , PRODUCT_ID
        , USER_ID

특정 세대의 대장균 찾기

3세대의 대장균의 ID(ID) 를 출력하는 SQL 문을 작성해주세요. 이때 결과는 대장균의 ID 에 대해 오름차순 정렬해주세요.

   SELECT A.ID
     FROM ECOLI_DATA A
LEFT JOIN ECOLI_DATA B
       ON A. PARENT_ID = B.ID
LEFT JOIN ECOLI_DATA C
       ON B.PARENT_ID = C.ID
    WHERE B.PARENT_ID IS NOT NULL 
      AND C.PARENT_ID IS NULL
 ORDER BY A.ID




GROUP BY



입양 시각 구하기(2)

보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.

   SELECT HOUR
        , COUNT(ANIMAL_ID) AS COUNT
     FROM (
           SELECT ROW_NUMBER() OVER() -1 AS HOUR 
             FROM ANIMAL_OUTS LIMIT 24
          ) A
LEFT JOIN ANIMAL_OUTS B
       ON A.HOUR = HOUR(B.DATETIME)
 GROUP BY HOUR
 ORDER BY HOUR

식품분류별 가장 비싼 식품의 정보 조회하기

FOOD_PRODUCT 테이블에서 식품분류별로 가격이 제일 비싼 식품의 분류, 가격, 이름을 조회하는 SQL문을 작성해주세요. 이때 식품분류가 '과자', '국', '김치', '식용유'인 경우만 출력시켜 주시고 결과는 식품 가격을 기준으로 내림차순 정렬해주세요.

  SELECT CATEGORY
       , PRICE AS MAX_PRICE
       , PRODUCT_NAME
    FROM FOOD_PRODUCT 
   WHERE (CATEGORY, PRICE) IN (
                                  SELECT CATEGORY
                                       , MAX(PRICE)
                                    FROM FOOD_PRODUCT 
                                GROUP BY CATEGORY
                                  HAVING CATEGORY IN ('과자', '국', '김치', '식용유')
                              )
ORDER BY MAX_PRICE DESC

년, 월, 성별 별 상품 구매 회원 수 구하기

USER_INFO 테이블과 ONLINE_SALE 테이블에서 년, 월, 성별 별로 상품을 구매한 회원수를 집계하는 SQL문을 작성해주세요. 결과는 년, 월, 성별을 기준으로 오름차순 정렬해주세요. 이때, 성별 정보가 없는 경우 결과에서 제외해주세요.

  SELECT YEAR(SALES_DATE) AS YEAR
       , MONTH(SALES_DATE) AS MONTH
       , A.GENDER
       , COUNT(DISTINCT A.USER_ID) AS USERS
    FROM USER_INFO A
    JOIN ONLINE_SALE B
      ON A.USER_ID = B.USER_ID
GROUP BY YEAR(SALES_DATE)
       , MONTH(SALES_DATE), A.GENDER
  HAVING A.GENDER IS NOT NULL
ORDER BY YEAR
       , MONTH
       , GENDER

저자 별 카테고리 별 매출액 집계하기

2022년 1월의 도서 판매 데이터를 기준으로 저자 별, 카테고리 별 매출액(TOTAL_SALES = 판매량 * 판매가) 을 구하여, 저자 ID(AUTHOR_ID), 저자명(AUTHOR_NAME), 카테고리(CATEGORY), 매출액(SALES) 리스트를 출력하는 SQL문을 작성해주세요.
결과는 저자 ID를 오름차순으로, 저자 ID가 같다면 카테고리를 내림차순 정렬해주세요.

   SELECT C.AUTHOR_ID
        , C.AUTHOR_NAME
        , B.CATEGORY
        , SUM(B.PRICE * A.SALES) AS TOTAL_SALES 
     FROM BOOK_SALES A
LEFT JOIN BOOK B
       ON A.BOOK_ID = B.BOOK_ID
LEFT JOIN AUTHOR C
       ON B.AUTHOR_ID = C.AUTHOR_ID
    WHERE A.SALES_DATE LIKE '2022-01%'
 GROUP BY C.AUTHOR_ID
        , B.CATEGORY
 ORDER BY C.AUTHOR_ID
        , B.CATEGORY DESC

언어별 개발자 분류하기

DEVELOPERS 테이블에서 GRADE별 개발자의 정보를 조회하려 합니다. GRADE는 다음과 같이 정해집니다.

  • A : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
  • B : C# 스킬을 가진 개발자
  • C : 그 외의 Front End 개발자
    GRADE가 존재하는 개발자의 GRADE, ID, EMAIL을 조회하는 SQL 문을 작성해 주세요.
    결과는 GRADE와 ID를 기준으로 오름차순 정렬해 주세요.
  SELECT *
    FROM (
          SELECT CASE WHEN SKILL_CODE & (SELECT CODE 
                                           FROM SKILLCODES 
                                          WHERE NAME = 'Python') 
                           AND SKILL_CODE & (SELECT SUM(CODE) 
                                               FROM SKILLCODES 
                                           GROUP BY CATEGORY 
                                             HAVING CATEGORY = 'Front End') THEN 'A'
                      WHEN SKILL_CODE & (SELECT CODE 
                                           FROM SKILLCODES 
                                          WHERE NAME = 'C#') THEN 'B'
                      WHEN SKILL_CODE & (SELECT SUM(CODE) 
                                           FROM SKILLCODES 
                                       GROUP BY CATEGORY 
                                         HAVING CATEGORY = 'Front End') THEN 'C'
                 END AS GRADE
               , ID
               , EMAIL           
            FROM DEVELOPERS
         ) A
   WHERE GRADE IS NOT NULL
ORDER BY GRADE, ID

연간 평가점수에 해당하는 평가 등급 및 성과금 조회하기

HR_DEPARTMENT, HR_EMPLOYEES, HR_GRADE 테이블을 이용해 사원별 성과금 정보를 조회하려합니다. 평가 점수별 등급과 등급에 따른 성과금 정보가 아래와 같을 때, 사번, 성명, 평가 등급, 성과금을 조회하는 SQL문을 작성해주세요.
평가등급의 컬럼명은 GRADE로, 성과금의 컬럼명은 BONUS로 해주세요.
결과는 사번 기준으로 오름차순 정렬해주세요.

   SELECT A.EMP_NO
        , A.EMP_NAME
        , CASE WHEN AVG(C.SCORE) >= 96 THEN 'S'
               WHEN AVG(C.SCORE) >= 90 THEN 'A'
               WHEN AVG(C.SCORE) >= 80 THEN 'B'
               ELSE 'C'
          END AS GRADE
        , CASE WHEN AVG(C.SCORE) >= 96 THEN A.SAL * 0.2
               WHEN AVG(C.SCORE) >= 90 THEN A.SAL * 0.15
               WHEN AVG(C.SCORE) >= 80 THEN A.SAL * 0.1
               ELSE 0
          END AS BONUS
     FROM HR_EMPLOYEES A
LEFT JOIN HR_DEPARTMENT B
       ON A.DEPT_ID = B.DEPT_ID
LEFT JOIN HR_GRADE C
       ON A.EMP_NO = C.EMP_NO
 GROUP BY A.EMP_NO
 ORDER BY A.EMP_NO




JOIN



보호소에서 중성화한 동물

보호소에서 중성화 수술을 거친 동물 정보를 알아보려 합니다. 보호소에 들어올 당시에는 중성화1되지 않았지만, 보호소를 나갈 당시에는 중성화된 동물의 아이디와 생물 종, 이름을 조회하는 아이디 순으로 조회하는 SQL 문을 작성해주세요.

   SELECT A.ANIMAL_ID
        , A.ANIMAL_TYPE
        , A.NAME
     FROM ANIMAL_INS A
LEFT JOIN ANIMAL_OUTS B
       ON A.ANIMAL_ID = B.ANIMAL_ID
    WHERE A.SEX_UPON_INTAKE LIKE "Intact%"
      AND (B.SEX_UPON_OUTCOME LIKE "Spayed%" 
           OR B.SEX_UPON_OUTCOME LIKE "Neutered%")
 ORDER BY 1

5월 식품들의 총매출 조회하기

FOOD_PRODUCT와 FOOD_ORDER 테이블에서 생산일자가 2022년 5월인 식품들의 식품 ID, 식품 이름, 총매출을 조회하는 SQL문을 작성해주세요. 이때 결과는 총매출을 기준으로 내림차순 정렬해주시고 총매출이 같다면 식품 ID를 기준으로 오름차순 정렬해주세요.

   SELECT A.PRODUCT_ID
        , A.PRODUCT_NAME
        , SUM(A.PRICE * B.AMOUNT) AS TOTAL_SALES
     FROM FOOD_PRODUCT A
LEFT JOIN FOOD_ORDER B
       ON A.PRODUCT_ID = B.PRODUCT_ID
    WHERE B.PRODUCE_DATE LIKE '2022-05%' 
 GROUP BY A.PRODUCT_ID
 ORDER BY TOTAL_SALES DESC
        , A.PRODUCT_ID

그룹별 조건에 맞는 식당 목록 출력하기

MEMBER_PROFILE와 REST_REVIEW 테이블에서 리뷰를 가장 많이 작성한 회원의 리뷰들을 조회하는 SQL문을 작성해주세요. 회원 이름, 리뷰 텍스트, 리뷰 작성일이 출력되도록 작성해주시고, 결과는 리뷰 작성일을 기준으로 오름차순, 리뷰 작성일이 같다면 리뷰 텍스트를 기준으로 오름차순 정렬해주세요.

   SELECT A.MEMBER_NAME
        , B.REVIEW_TEXT
        , DATE_FORMAT(B.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE
     FROM MEMBER_PROFILE A
LEFT JOIN (
            SELECT *
                 , COUNT(0) OVER (PARTITION BY MEMBER_ID) AS MAX_NUM
              FROM REST_REVIEW 
           ) B
       ON A.MEMBER_ID = B.MEMBER_ID   
    WHERE B.MAX_NUM = (   
                          SELECT COUNT(0) 
                            FROM REST_REVIEW
                        GROUP BY MEMBER_ID
                        ORDER BY 1 DESC
                           LIMIT 1
                      )
 ORDER BY REVIEW_DATE
        , REVIEW_TEXT

주문량이 많은 아이스크림들 조회하기

7월 아이스크림 총 주문량과 상반기의 아이스크림 총 주문량을 더한 값이 큰 순서대로 상위 3개의 맛을 조회하는 SQL 문을 작성해주세요.

   SELECT A.FLAVOR
     FROM FIRST_HALF A
LEFT JOIN JULY B
       ON A.FLAVOR = B.FLAVOR
 GROUP BY B.FLAVOR
 ORDER BY A.TOTAL_ORDER + SUM(B.TOTAL_ORDER) DESC
    LIMIT 3

특정 기간동안 대여 가능한 자동차들의 대여비용 구하기

CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블과 CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블에서 자동차 종류가 '세단' 또는 'SUV' 인 자동차 중 2022년 11월 1일부터 2022년 11월 30일까지 대여 가능하고 30일간의 대여 금액이 50만원 이상 200만원 미만인 자동차에 대해서 자동차 ID, 자동차 종류, 대여 금액(컬럼명: FEE) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 대여 금액을 기준으로 내림차순 정렬하고, 대여 금액이 같은 경우 자동차 종류를 기준으로 오름차순 정렬, 자동차 종류까지 같은 경우 자동차 ID를 기준으로 내림차순 정렬해주세요.

   SELECT DISTINCT A.CAR_ID
        , A.CAR_TYPE
        , ROUND((A.DAILY_FEE - A.DAILY_FEE * (C.DISCOUNT_RATE * 0.01)) * 30) AS FEE
     FROM CAR_RENTAL_COMPANY_CAR A
LEFT JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY B
       ON A.CAR_ID = B.CAR_ID
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN C
       ON A.CAR_TYPE = C.CAR_TYPE
      AND C.DURATION_TYPE = '30일 이상'
    WHERE A.CAR_TYPE IN ('세단', 'SUV')
      AND A.CAR_ID NOT IN (
                            SELECT DISTINCT CAR_ID
                              FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
                             WHERE START_DATE LIKE '2022-11%' 
                                OR END_DATE LIKE '2022-11%'
                                OR START_DATE <= '2022-11-01' 
                               AND END_DATE >= '2022-11-30'
                          )
      AND ROUND((A.DAILY_FEE - A.DAILY_FEE * (C.DISCOUNT_RATE * 0.01)) * 30) >= 500000
      AND ROUND((A.DAILY_FEE - A.DAILY_FEE * (C.DISCOUNT_RATE * 0.01)) * 30) < 2000000
 ORDER BY FEE DESC
        , A.CAR_TYPE
        , B.CAR_ID DESC

FrontEnd 개발자 찾기

DEVELOPERS 테이블에서 Front End 스킬을 가진 개발자의 정보를 조회하려 합니다. 조건에 맞는 개발자의 ID, 이메일, 이름, 성을 조회하는 SQL 문을 작성해 주세요.
결과는 ID를 기준으로 오름차순 정렬해 주세요.

  SELECT DISTINCT A.ID
       , A.EMAIL
       , A.FIRST_NAME
       , A.LAST_NAME
    FROM DEVELOPERS A
    JOIN SKILLCODES B
      ON A.SKILL_CODE & B.CODE
     AND B.CATEGORY = 'Front End'
ORDER BY A.ID




String, Date



취소되지 않은 진료 예약 조회하기

PATIENT, DOCTOR 그리고 APPOINTMENT 테이블에서 2022년 4월 13일 취소되지 않은 흉부외과(CS) 진료 예약 내역을 조회하는 SQL문을 작성해주세요. 진료예약번호, 환자이름, 환자번호, 진료과코드, 의사이름, 진료예약일시 항목이 출력되도록 작성해주세요. 결과는 진료예약일시를 기준으로 오름차순 정렬해주세요.

  SELECT APNT_NO
       , PT_NAME
       , A.PT_NO
       , B.MCDP_CD
       , DR_NAME
       , APNT_YMD
    FROM PATIENT A
    JOIN APPOINTMENT B
      ON A.PT_NO = B.PT_NO
    JOIN DOCTOR C
      ON B.MDDR_ID = C.DR_ID
   WHERE B.APNT_CNCL_YN != 'Y'
     AND B.MCDP_CD = 'CS'
     AND APNT_YMD LIKE '2022-04-13%'
ORDER BY APNT_YMD

자동차 대여 기록 별 대여 금액 구하기

CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블과 CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블에서 자동차 종류가 '트럭'인 자동차의 대여 기록에 대해서 대여 기록 별로 대여 금액(컬럼명: FEE)을 구하여 대여 기록 ID와 대여 금액 리스트를 출력하는 SQL문을 작성해주세요. 결과는 대여 금액을 기준으로 내림차순 정렬하고, 대여 금액이 같은 경우 대여 기록 ID를 기준으로 내림차순 정렬해주세요.

   SELECT B.HISTORY_ID
        , FLOOR((A.DAILY_FEE 
                 - A.DAILY_FEE 
                 * (IFNULL((
                             SELECT C.DISCOUNT_RATE
                               FROM CAR_RENTAL_COMPANY_DISCOUNT_PLAN  C
                              WHERE C.CAR_TYPE = A.CAR_TYPE
                                AND C.DURATION_TYPE = CASE WHEN DATEDIFF(B.END_DATE, B.START_DATE) + 1 >= 90 THEN '90일 이상'
                                                           WHEN DATEDIFF(B.END_DATE, B.START_DATE) + 1 >= 30 THEN '30일 이상'
                                                           WHEN DATEDIFF(B.END_DATE, B.START_DATE) + 1 >= 7 THEN '7일 이상'
                                                           ELSE NULL
                                                      END
                           ), 0) 
                 * 0.01)) 
          * (DATEDIFF(B.END_DATE, B.START_DATE) + 1)) AS FEE
     FROM CAR_RENTAL_COMPANY_CAR A
LEFT JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY B
       ON A.CAR_ID = B.CAR_ID
    WHERE A.CAR_TYPE = '트럭'
 ORDER BY FEE DESC
        , B.HISTORY_ID DESC




Summer/Winter Coding(2019)



우유와 요거트가 담긴 장바구니

데이터 분석 팀에서는 우유(Milk)와 요거트(Yogurt)를 동시에 구입한 장바구니가 있는지 알아보려 합니다. 우유와 요거트를 동시에 구입한 장바구니의 아이디를 조회하는 SQL 문을 작성해주세요. 이때 결과는 장바구니의 아이디 순으로 나와야 합니다.

  SELECT A.CART_ID
    FROM (
           SELECT CART_ID
             FROM CART_PRODUCTS
            WHERE NAME = 'MILK'
         ) A
    JOIN (
           SELECT CART_ID
             FROM CART_PRODUCTS
            WHERE NAME = 'YOGURT'
         ) B
      ON A.CART_ID = B.CART_ID
ORDER BY A.CART_ID




Lv.5


SELECT



멸종위기의 대장균 찾기

각 세대별 자식이 없는 개체의 수(COUNT)와 세대(GENERATION)를 출력하는 SQL문을 작성해주세요. 이때 결과는 세대에 대해 오름차순 정렬해주세요. 단, 모든 세대에는 자식이 없는 개체가 적어도 1개체는 존재합니다.

WITH RECURSIVE GENERATION AS(
       SELECT ID
            , 1 AS LEVEL
         FROM ECOLI_DATA 
        WHERE PARENT_ID IS NULL
    UNION ALL
       SELECT E.ID
            , G.LEVEL + 1 AS LEVEL
         FROM ECOLI_DATA E
         JOIN GENERATION G
           ON E.PARENT_ID = G.ID
)
   SELECT COUNT(G.ID) AS COUNT
        , LEVEL AS GENERATION
     FROM GENERATION G
LEFT JOIN ECOLI_DATA E
       ON G.ID = E.PARENT_ID
    WHERE E.ID IS NULL
 GROUP BY LEVEL
 ORDER BY LEVEL




JOIN



상품을 구매한 회원 비율 구하기

USER_INFO 테이블과 ONLINE_SALE 테이블에서 2021년에 가입한 전체 회원들 중 상품을 구매한 회원수와 상품을 구매한 회원의 비율(=2021년에 가입한 회원 중 상품을 구매한 회원수 / 2021년에 가입한 전체 회원 수)을 년, 월 별로 출력하는 SQL문을 작성해주세요. 상품을 구매한 회원의 비율은 소수점 두번째자리에서 반올림하고, 전체 결과는 년을 기준으로 오름차순 정렬해주시고 년이 같다면 월을 기준으로 오름차순 정렬해주세요.

  SELECT YEAR(B.SALES_DATE) AS YEAR
       , MONTH(B.SALES_DATE) AS MONTH
       , COUNT(DISTINCT A.USER_ID) AS PUCHASED_USERS
       , ROUND(COUNT(DISTINCT A.USER_ID) / (SELECT COUNT(0) 
                                              FROM USER_INFO WHERE YEAR(JOINED) = '2021'
                                           ), 1) AS PUCHASED_RATIO
    FROM USER_INFO A
    JOIN ONLINE_SALE B
      ON A.USER_ID = B.USER_ID
   WHERE YEAR(A.JOINED) = '2021'
GROUP BY YEAR(B.SALES_DATE)
       , MONTH(B.SALES_DATE)
ORDER BY YEAR(B.SALES_DATE)
       , MONTH(B.SALES_DATE)

0개의 댓글