https://school.programmers.co.kr/learn/courses/30/lessons/77487#qna
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제
이 서비스에서는 공간을 둘 이상 등록한 사람을 "헤비 유저"라고 부릅니다. 헤비 유저가 등록한 공간의 정보를 아이디 순으로 조회하는 SQL문을 작성해주세요.
예시
예를 들어, PLACES 테이블이 다음과 같다면
ID | NAME | HOST_ID |
4431977 | BOUTIQUE STAYS - Somerset Terrace, Pet Friendly | 760849 |
5194998 | BOUTIQUE STAYS - Elwood Beaches 3, Pet Friendly | 760849 |
16045624 | Urban Jungle in the Heart of Melbourne | 30900122 |
17810814 | Stylish Bayside Retreat with a Luscious Garden | 760849 |
22740286 | FREE PARKING - The Velvet Lux in Melbourne CBD | 30900122 |
22868779 | ★ Fresh Fitzroy Pad with City Views! ★ | 21058208 |
- 760849번 유저는 공간을 3개 등록했으므로 이 유저는 헤비유저입니다.
- 30900122번 유저는 공간을 2개 등록했으므로 이 유저는 헤비유저입니다.
- 21058208번 유저는 공간을 1개 등록했으므로 이 유저는 헤비유저가 아닙니다.
따라서 SQL 문을 실행하면 다음과 같이 나와야 합니다.
ID | NAME | HOST_ID |
4431977 | BOUTIQUE STAYS - Somerset Terrace, Pet Friendly | 760849 |
5194998 | BOUTIQUE STAYS - Elwood Beaches 3, Pet Friendly | 760849 |
16045624 | Urban Jungle in the Heart of Melbourne | 30900122 |
17810814 | Stylish Bayside Retreat with a Luscious Garden | 760849 |
22740286 | FREE PARKING - The Velvet Lux in Melbourne CBD | 30900122 |
이 문제는 일반적인 GROUP BY와 조건절로는 해결하기 어려운 문제이다. HOST_ID의 중복값이 2개 이상인 경우만을 출력하는 문제인데 결과 테이블을 보면 그룹화가 되어 있지 않다. 즉 조건절을 이용해야 하는 문제이다.
SELECT ID,NAME,HOST_ID FROM PLACES
WHERE COUNT(HOST_ID) > 1
위 코드는 SELECT문에서 COUNT를 이용하지 않았기 때문에 WHERE절에 COUNT를 사용할 수 없다. 그렇다고 그룹화도 할 수 없는 상황이다. 필자는 임의의 테이블을 하나 더 만들어서 JOIN하는 법을 생각했다.
정답
SELECT A.ID,A.NAME,A.HOST_ID FROM PLACES AS A
LEFT JOIN
(SELECT HOST_ID, COUNT(HOST_ID) AS COUNT FROM PLACES
GROUP BY HOST_ID) AS B
ON A.HOST_ID=B.HOST_ID
WHERE B.COUNT >1
ORDER BY ID
우선 임의의 테이블 B를 보면 HOST_ID를 기준으로 그룹화한 테이블이다.
HOST_ID | COUNT |
5507453 | 1 |
760849 | 3 |
20584468 | 1 |
10810140 | 1 |
30900122 | 2 |
129348781 | 1 |
133472555 | 1 |
21058208 | 1 |
31634799 | 1 |
8209200 | 1 |
210035490 | 1 |
다음과 같은 테이블B를 A에 HOST_ID를 기준으로 LEFT JOIN하면 다음과 같은 테이블이 나온다.
ID | NAME | HOST_ID |
1001457 | Docklands Apartment with River Views | 5507453 |
4431977 | BOUTIQUE STAYS - Somerset Terrace, Pet Friendly | 760849 |
5194998 | BOUTIQUE STAYS - Elwood Beaches 3, Pet Friendly | 760849 |
11762465 | Fabulous single room | 20584468 |
13627321 | Sunny, Modern Apartment with Cityscape Views | 10810140 |
16045624 | Urban Jungle in the Heart of Melbourne | 30900122 |
17810814 | Stylish Bayside Retreat with a Luscious Garden | 760849 |
20351923 | 11 - 4608SB · 11*2Bd2Bth Lv46*skyline view*door step to Crown | 129348781 |
22002927 | Junction of CBD,Casino&Yarra River* FREE PARKING | 133472555 |
22740286 | FREE PARKING - The Velvet Lux in Melbourne CBD | 30900122 |
22868779 | ★ Fresh Fitzroy Pad with City Views! ★ | 21058208 |
24195416 | 5 Star Luxury St Kilda Road | 31634799 |
28400921 | Southbank Top Amazing CityView 2BR Apartment | 8209200 |
28848587 | [Crown] 2BR/FREE PARKING/HIGH RISE/NETFLIX/DBAE | 210035490 |
여기서 WHERE절을 이용해 문제를 해결했다. 그 후 더 간단한 코드를 찾아보았다.
SELECT * FROM PLACES
WHERE HOST_ID IN (SELECT HOST_ID FROM PLACES GROUP BY HOST_ID HAVING COUNT(HOST_ID) > 1)
ORDER BY ID
WHERE과 IN을 이용해 더 간단하게 하는 방법이 있었다.
'SQL' 카테고리의 다른 글
GROUP_CONCAT 응용 (0) | 2023.01.02 |
---|---|
서브퀴리 응용(2) (0) | 2023.01.01 |
JOIN, GROUP BY를 동시에 사용하는 경우 (0) | 2022.12.29 |
FLOOR를 응용한 문제 (0) | 2022.12.27 |
SQL) LEFT JOIN(2) (0) | 2022.12.26 |