SQL

서브쿼리 응용

zzugest1 2022. 12. 30. 14:41

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