Backend
home
4️⃣

Level4

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

SELECT RI.REST_ID, RI.REST_NAME, RI.FOOD_TYPE, RI.FAVORITES, RI.ADDRESS, ROUND(AVG(RR.REVIEW_SCORE), 2) AS SCORE FROM REST_INFO RI JOIN REST_REVIEW RR ON RI.REST_ID = RR.REST_ID WHERE RI.ADDRESS LIKE '서울%' GROUP BY RI.REST_ID, RI.REST_NAME, RI.FOOD_TYPE, RI.FAVORITES, RI.ADDRESS ORDER BY SCORE DESC, RI.FAVORITES DESC;
SQL
복사

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

-- 코드를 입력하세요 SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT FROM ONLINE_SALE WHERE SALES_DATE >= '2022-03-01' AND SALES_DATE < '2022-04-01' 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 SALES_DATE >= '2022-03-01' AND SALES_DATE < '2022-04-01' ORDER BY SALES_DATE ASC, PRODUCT_ID ASC, USER_ID ASC;
SQL
복사

3. 특정 세대의 대장균 찾기

SELECT C3.ID FROM ECOLI_DATA AS C3 JOIN ECOLI_DATA AS C2 ON C3.PARENT_ID = C2.ID JOIN ECOLI_DATA AS C1 ON C2.PARENT_ID = C1.ID WHERE C1.PARENT_ID IS NULL ORDER BY C3.ID;
SQL
복사

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

SELECT a.AUTHOR_ID, a.AUTHOR_NAME, b.CATEGORY, SUM(bs.SALES * b.PRICE) AS TOTAL_SALES FROM BOOK_SALES bs JOIN BOOK b ON bs.BOOK_ID = b.BOOK_ID JOIN AUTHOR a ON b.AUTHOR_ID = a.AUTHOR_ID WHERE bs.SALES_DATE BETWEEN '2022-01-01' AND '2022-01-31' GROUP BY a.AUTHOR_ID, a.AUTHOR_NAME, b.CATEGORY ORDER BY a.AUTHOR_ID ASC, b.CATEGORY DESC;
SQL
복사

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

SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME FROM FOOD_PRODUCT WHERE (CATEGORY, PRICE) IN ( SELECT CATEGORY, MAX(PRICE) FROM FOOD_PRODUCT WHERE CATEGORY IN ('과자', '국', '김치', '식용유') GROUP BY CATEGORY ) ORDER BY MAX_PRICE DESC; -- 윈도우 함수 사용 SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME FROM ( SELECT *, RANK() OVER (PARTITION BY CATEGORY ORDER BY PRICE DESC) AS rnk FROM FOOD_PRODUCT WHERE CATEGORY INT ('과자', '국', '김치', '식용유') ) AS ranked WHERE rnk = 1 ORDER BY MAX_PRICE DESC;
SQL
복사

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

SELECT YEAR(SALES_DATE) AS YEAR, MONTH(SALES_DATE) AS MONTH, U.GENDER, COUNT(DISTINCT U.USER_ID) AS USERS FROM USER_INFO U JOIN ONLINE_SALE O ON U.USER_ID = O.USER_ID WHERE GENDER IN (1, 0) GROUP BY YEAR, MONTH, U.GENDER ORDER BY YEAR, MONTH, U.GENDER; -- 참고 WITH monthly_users AS ( SELECT YEAR(O.SALES_DATE) AS YEAR, MONTH(O.SALES_DATE) AS MONTH, O.USER_ID FROM ONLINE_SALE O /* WHERE O.SALES_DATE >= '2021-01-01' AND O.SALES_DATE < '2022-01-01' */ GROUP BY YEAR, MONTH, O.USER_ID ) SELECT MU.YEAR, MU.MONTH, U.GENDER, COUNT(*) AS USERS FROM monthly_users MU JOIN USER_INFO U ON U.USER_ID = MU.USER_ID WHERE U.GENDER IN (0, 1) -- 또는 U.GENDER IS NOT NULL GROUP BY MU.YEAR, MU.MONTH, U.GENDER ORDER BY MU.YEAR, MU.MONTH, U.GENDER;
SQL
복사

7. 입양 시각 구하기 (2)

SELECT H.h AS HOUR, COALESCE(A.cnt, 0) AS COUNT FROM ( SELECT 0 AS h UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20 UNION ALL SELECT 21 UNION ALL SELECT 22 UNION ALL SELECT 23 ) AS H LEFT JOIN ( SELECT HOUR(DATETIME) AS h, COUNT(*) AS cnt FROM ANIMAL_OUTS GROUP BY HOUR(DATETIME) ) AS A ON A.h = H.h ORDER BY H.h;
SQL
복사

8. 언어별 개발자 분류하기

SELECT CASE WHEN (d.SKILL_CODE & py.py_code) > 0 AND (d.SKILL_CODE & fe.front_mask) > 0 THEN 'A' WHEN (d.SKILL_CODE & cs.cs_code) > 0 THEN 'B' WHEN (d.SKILL_CODE & fe.front_mask) > 0 THEN 'C' END AS GRADE, d.ID, d.EMAIL FROM DEVELOPERS d -- 카테고리 'Front end'의 모든 CODE를 합쳐 1개의 비트마스크로 만든다. JOIN ( SELECT SUM(CODE) AS front_mask FROM SKILLCODES WHERE CATEGORY = 'Front End' ) fe -- Python, C#의 코드 값을 각각 가져온다. JOIN ( SELECT CODE AS py_code FROM SKILLCODES WHERE NAME = 'Python' ) py JOIN ( SELECT CODE AS cs_code FROM SKILLCODES WHERE NAME = 'C#' ) cs -- 등급이 부여되는 경우만 남긴다(A/B/C) WHERE ((d.SKILL_CODE & py.py_code) > 0 AND (d.SKILL_CODE & fe.front_mask) > 0) OR ((d.SKILL_CODE & cs.cs_code) > 0) OR ((d.SKILL_CODE & fe.front_mask) > 0) ORDER BY GRADE, d.ID;
SQL
복사

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

SELECT E.EMP_NO, E.EMP_NAME, CASE WHEN G.AVG_SCORE >= 96 THEN 'S' WHEN G.AVG_SCORE >= 90 THEN 'A' WHEN G.AVG_SCORE >= 80 THEN 'B' ELSE 'C' END AS GRADE, /* 정수로 만들고 싶으면 CAST(...) AS SIGNED 혹은 FLOOR(...) 사용 */ CASE WHEN G.AVG_SCORE >= 96 THEN E.SAL * 0.20 WHEN G.AVG_SCORE >= 90 THEN E.SAL * 0.15 WHEN G.AVG_SCORE >= 80 THEN E.SAL * 0.10 ELSE 0 END AS BONUS FROM HR_EMPLOYEES E JOIN ( SELECT EMP_NO, AVG(SCORE) AS AVG_SCORE FROM HR_GRADE GROUP BY EMP_NO ) G ON G.EMP_NO = E.EMP_NO ORDER BY E.EMP_NO;
SQL
복사

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

SELECT f.FLAVOR FROM FIRST_HALF f LEFT JOIN ( SELECT FLAVOR, SUM(TOTAL_ORDER) AS july_total FROM JULY GROUP BY FLAVOR ) j ON j.FLAVOR = f.FLAVOR GROUP BY f.FLAVOR, f.TOTAL_ORDER, j.july_total ORDER BY (f.TOTAL_ORDER + COALESCE(j.july_total, 0)) DESC LIMIT 3;
SQL
복사

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

SELECT F.PRODUCT_ID, F.PRODUCT_NAME, SUM(F.PRICE * O.AMOUNT) AS TOTAL_SALES FROM FOOD_PRODUCT F JOIN FOOD_ORDER O ON F.PRODUCT_ID = O.PRODUCT_ID WHERE O.PRODUCE_DATE BETWEEN '2022-05-01' AND '2022-05-31' GROUP BY F.PRODUCT_ID, F.PRODUCT_NAME ORDER BY TOTAL_SALES DESC, F.PRODUCT_ID ASC; -- 성능 고려 -- 포함(>=) ~ 배제(<) 형태를 권장 SELECT p.PRODUCT_ID, p.PRODUCT_NAME, p.PRICE * s.total_amount AS TOTAL_SALES FROM FOOD_PRODUCT p JOIN ( SELECT PRODUCT_ID, SUM(AMOUNT) AS total_amount FROM FOOD_ORDER WHERE PRODUCE_DATE >= '2022-05-01' AND PRODUCE_DATE < '2022-06-01' GROUP BY PRODUCT_ID ) s ON p.PRODUCT_ID = s.PRODUCT_ID ORDER BY TOTAL_SALES DESC, p.PRODUCT_ID ASC;
SQL
복사