DB , SQL/SQL - 1일 1쿼리

[SQL] 26년 4월 : 1일 1쿼리

subindev 2026. 4. 2. 14:02

프로젝트로 모바일을 하다보니 직접 SQL 작성하는 일이 드물다.

그래서 실력 향상 및 복습을 위해 1일 1쿼리를 다시 시작하려한다.

 

2026.04.01(수)

 

프로그래머스 > 코딩테스트 연습 > JOIN > 그룹별 조건에 맞는 식당 출력

https://school.programmers.co.kr/learn/courses/30/lessons/131124

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

정답

SELECT
    M.MEMBER_NAME,
    R.REVIEW_TEXT,
    DATE_FORMAT(R.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE
FROM MEMBER_PROFILE M
JOIN REST_REVIEW R
    ON M.MEMBER_ID = R.MEMBER_ID
WHERE R.MEMBER_ID IN (
    SELECT MEMBER_ID
    FROM REST_REVIEW
    GROUP BY MEMBER_ID
    HAVING COUNT(*) = (
        SELECT COUNT(*)
        FROM REST_REVIEW
        GROUP BY MEMBER_ID
        ORDER BY COUNT(*) DESC
        LIMIT 1
    )
)
ORDER BY R.REVIEW_DATE ASC, R.REVIEW_TEXT ASC;

 

아직 서브쿼리는 헷갈리고 약간 어렵다. 서브 쿼리 위주의 문제를 더 풀어봐야겠다.

 풀이 과정

SELECT COUNT(*)
FROM REST_REVIEW AS R
GROUP BY MEMBER_ID 
ORDER BY COUNT(*) DESC 
LIMIT 1;


(SELECT MEMBER_ID
FROM REST_REVIEW AS R
GROUP BY MEMBER_ID
HAVING COUNT(*) = 
    (SELECT COUNT(*)
    FROM REST_REVIEW AS R
    GROUP BY MEMBER_ID 
    ORDER BY COUNT(*) DESC 
    LIMIT 1)
);

-- COUNT를 알아내지 않고 LIMIT 1을 쓰면 제일 많이 쓴 횟수가 3인 사용자가 여러명일때 문제가 됨

SELECT M.MEMBER_NAME, R.REVIEW_TEXT, R.REVIEW_DATE
FROM MEMBER_PROFILE AS M
JOIN REST_REVIEW AS R
ON M.MEMBER_ID = R.MEMBER_ID
WHERE R.MEMBER_ID IN 
    (SELECT MEMBER_ID
    FROM REST_REVIEW AS R
    GROUP BY MEMBER_ID
    HAVING COUNT(*) = 
        (SELECT COUNT(*)
        FROM REST_REVIEW AS R
        GROUP BY MEMBER_ID 
        ORDER BY COUNT(*) DESC 
        LIMIT 1)
    )
ORDER BY R.REVIEW_DATE, R.REVIEW_TEXT

 

바로 답을 유추하기 보다는 제일 먼저 필요한 쿼리를 작성하고 거기 덧붙혀나가는 식으로 하는 것이 더욱 나에게 맞는 풀이법 인 것 같다.

 

 

 


2026.04.02(목)

프로그래머스 > 코딩테스트 연습 > JOIN > 그룹별 조건에 맞는 식당 출력

https://school.programmers.co.kr/learn/courses/30/lessons/293261

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

정답

#SELECT FISH_TYPE, MAX(LENGTH) FROM FISH_INFO GROUP BY FISH_TYPE;

SELECT 
    FI.ID, 
    NI.FISH_NAME, 
    FI.LENGTH
FROM FISH_INFO AS FI
JOIN 
    (SELECT 
        FISH_TYPE, 
        MAX(LENGTH) AS LENGTH 
     FROM FISH_INFO 
     GROUP BY FISH_TYPE) M
ON FI.FISH_TYPE = M.FISH_TYPE
AND FI.LENGTH = M.LENGTH
JOIN FISH_NAME_INFO AS NI
ON FI.FISH_TYPE = NI.FISH_TYPE
ORDER BY FI.ID ;

 

서브 쿼리를 조인하는 방식으로 풀 수 있었다.
이외에도 상관 서브쿼리 방식으로 풀 수도 있었다.

 

SELECT FI.ID, FNI.FISH_NAME, FI.LENGTH
FROM FISH_INFO FI
JOIN FISH_NAME_INFO FNI
    ON FI.FISH_TYPE = FNI.FISH_TYPE
WHERE FI.LENGTH = (
    SELECT MAX(FI2.LENGTH)
    FROM FISH_INFO FI2
    WHERE FI2.FISH_TYPE = FI.FISH_TYPE
)
ORDER BY FI.ID;

 


 

2026.04.03(금)

 

프로그래머스 > 코딩테스트 연습 > JOIN > 즐겨찾기가 가장 많은 식당 정보 출력하기

https://school.programmers.co.kr/learn/courses/30/lessons/131123

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

-- 코드를 입력하세요
SELECT I.FOOD_TYPE, REST_ID, REST_NAME, I.FAVORITES
FROM REST_INFO I
JOIN( 
    SELECT 
        FOOD_TYPE, 
        MAX(FAVORITES) AS FAVORITES
    FROM REST_INFO
    GROUP BY FOOD_TYPE 
    ) M
    ON I.FOOD_TYPE = M.FOOD_TYPE
    AND I.FAVORITES = M.FAVORITES
ORDER BY I.FOOD_TYPE DESC

 


 

2026.04.06(월)

 

프로그래머스 > 코딩테스트 연습 > JOIN > 주문량이 많은 아이스크림들 조회하기

https://school.programmers.co.kr/learn/courses/30/lessons/133027

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

-- 코드를 입력하세요
SELECT F.FLAVOR
FROM FIRST_HALF F
JOIN JULY J
ON F.FLAVOR = J.FLAVOR
GROUP BY FLAVOR
ORDER BY SUM(F.TOTAL_ORDER + J.TOTAL_ORDER) DESC
LIMIT 3;

 

HAVING 절 안에 SUM 을 넣어보려고 고민하다가, 정렬 후 LIMIT으로 하는 방법으로 수정함

 

 


 

2026.04.07(화)

프로그래머스 > 코딩테스트 연습 > JOIN > 물고기 별 대어 찾기

https://school.programmers.co.kr/learn/courses/30/lessons/293261

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

SELECT I.ID, N.FISH_NAME, I.LENGTH
FROM FISH_INFO I
JOIN (
        SELECT FISH_TYPE, MAX(LENGTH) AS LENGTH
        FROM FISH_INFO
        GROUP BY FISH_TYPE
     ) M
    ON I.FISH_TYPE = M.FISH_TYPE
    AND I.LENGTH = M.LENGTH
JOIN FISH_NAME_INFO N
    ON N.FISH_TYPE = I.FISH_TYPE
ORDER BY I.ID;

 

 

 


 

2026.04.08(수)

프로그래머스 > 코딩테스트 연습 > JOIN > 상품을 구매한 회원 비율 구하기

https://school.programmers.co.kr/learn/courses/30/lessons/131534

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

SELECT YEAR(OS.SALES_DATE) AS YEAR,
       MONTH(OS.SALES_DATE) AS MONTH,
       COUNT(DISTINCT OS.USER_ID) AS PURCHASED_USERS,
       ROUND(COUNT(DISTINCT OS.USER_ID)/
             (SELECT COUNT(*)
             FROM USER_INFO
             WHERE YEAR(JOINED) = 2021
            ),1)
       AS PURCHASED_RATIO
FROM ONLINE_SALE OS 
JOIN USER_INFO UI
ON OS.USER_ID = UI.USER_ID
WHERE YEAR(UI.JOINED) = 2021
GROUP BY YEAR(OS.SALES_DATE), MONTH(OS.SALES_DATE)
ORDER BY YEAR, MONTH;

 

 


 

2026.04.09(목)

프로그래머스 > 코딩테스트 연습 > GROUP BY > 성분으로 구분한 아이스크림 총 주문량

https://school.programmers.co.kr/learn/courses/30/lessons/133026

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

SELECT 
    INGREDIENT_TYPE, 
    SUM(TOTAL_ORDER) AS TOTAL_ORDER
FROM FIRST_HALF H
JOIN ICECREAM_INFO I
    ON H.FLAVOR = I.FLAVOR
GROUP BY I.INGREDIENT_TYPE
ORDER BY TOTAL_ORDER

 

 

 


 

2026.04.10(금)

프로그래머스 > 코딩테스트 연습 > GROUP BY > 카테고리 별 도서 판매량 집계하기

SELECT 
    CATEGORY, 
    SUM(SALES) AS TOTAL_SALES
FROM BOOK_SALES S
JOIN BOOK B
    ON S.BOOK_ID = B.BOOK_ID
WHERE YEAR(SALES_DATE) = '2022' AND MONTH(SALES_DATE) = '1'
GROUP BY CATEGORY
ORDER BY CATEGORY;

 

 

2026.04.13(월)

프로그래머스 > 코딩테스트 연습 > GROUP BY > 조건에 맞는 사용자와 총 거래금액 조회하기

https://school.programmers.co.kr/learn/courses/30/lessons/164668

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

SELECT 
    WRITER_ID, 
    U.NICKNAME,
    SUM(PRICE) AS TOTAL_SALES
FROM USED_GOODS_BOARD B
JOIN USED_GOODS_USER U
    ON B.WRITER_ID = U.USER_ID
WHERE STATUS = 'DONE'
GROUP BY WRITER_ID
HAVING SUM(PRICE) >= 700000
ORDER BY SUM(PRICE)