본문 바로가기
SQL 문제 풀기/1. 프로그래머스 SQL : 2023.12.17~2024.2.29

<프로그래머스 59> 헤비 유저가 소유한 장소(Lv.3)

by HYEHYE_SON 2024. 2. 13.
728x90

 

프로그래머스에서 제공하는 SQL문제 매일 풀기 챌린지


 

2021 Dev-Matching:웹 백엔드 개발자(상반기) 문제

문제 설명

PLACES 테이블은 공간 임대 서비스에 등록된 공간의 정보를 담은 테이블입니다. PLACES 테이블의 구조는 다음과 같으며 IDNAMEHOST_ID는 각각 공간의 아이디, 이름, 공간을 소유한 유저의 아이디를 나타냅니다. ID는 기본키입니다

 

NAME TYPE
ID INT
NAME VARCHAR
HOST_ID INT

 


문제

이 서비스에서는 공간을 둘 이상 등록한 사람을 "헤비 유저"라고 부릅니다. 헤비 유저가 등록한 공간의 정보를 아이디 순으로 조회하는 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

♥ 정답

with pp as (select host_id, count(*)
    from places
    group by host_id
    having count(*) >= 2)
select p.id, p.name, pp.host_id
    from places p, pp
    where p.host_id = pp.host_id
    order by p.id asc;

이 문제는 
with절, group by절, EQUI JOIN
위 3가지를 사용하여 해결할 수 있다.


■ EQUI JOIN

조인은 여러 개의 테이블의 컬럼들을 활용하여 한 번에 원하는 것을 출력하고자 할 때 사용하는 문법이다.

그 중 EQUI JOIN 이란, 

조인하려는 테이블 사이에 공통된 컬럼이 있을 경우 (컬럼명은 달라도 되고, 데이터가 공통될 때)

EQUAL(=) 조인하는 조인 문법이다.

 

 

■ WITH .. AS 절

쉽게 말해서 with 절로 temp table을 구성하는 것인데,

create table이 아니라 with절을 사용해서 임시적으로 테이블을 만드는 것이다.

이 임시 테이블을 사용해서 테이블을 생성하여 select 시 활용할 수 있다.

WITH [new임시테이블명] AS 
	( 새로운 임시 테이블로 만들 쿼리문 )
select ....; --만든 쿼리문을 활용해서 검색할 쿼리문

 

with절로 생성한 임시 테이블은 temporart tablespace에 저장되고, 

그 결과를 temp 테이블로 구성되는 것이다.

 


 해설해보기

 

with .. as 절을 활용해서 새로운 테이블을 구성하고, 

그 테이블과 원래 테이블인 place를 equi join 하여 원하는 결과를 출력하면 된다.

 

 

 #WITH .. AS 절 내부 

 

우선 헤비 유저를 선별하는 쿼리부터 작성해야한다.

host_id 별 공간 임대 서브시에 등록된 공간 정보가 2개 이상인 유저를 선별해야하므로,

group by로 host_id를 묶어서 count(*) 한 후 

having절로 count(*) 개수가 2 이상인 host_id를 걸러내면 된다.

그럼 아래와 같은 결과가 출력된다.

select host_id, count(*)
    from places
    group by host_id
    having count(*) >= 2

 

이제 이 host_id에 대한 ID(공간의 ID), NAME(이름), HOST_ID(공간을 소유한 유저의 ID)를 출력해야하는데,선별된 host_id에 대한 정보만 출력하기 위해서는 위의 쿼리는 with.. as절을 사용해서 임시 테이블로 구성한 후 원래 테이블인 places와 equi join 해주면 된다.

 

위의 쿼리문을 임시테이블 pp로 이름을 지정해준 후 이 테이블을 사용할 쿼리문을 바로 아래에 작성해주면 된다.

 

 

 #WITH .. AS 절 외부 

 

기존 테이블인 places와 with 절로 생성한 pp 테이블을

공통된 컬럼인 host_id를 활용하여 EQUI JOIN 해준다.

 

따라서 

with절로 생성한 임시테이블 pp에서 선별된 host_id만 가져오고

기존 테이블인 places에서 id, name 컬럼을 가져오면,

결국 선별된 host_id에 대한 id, name, host_id에 대한 결과만 출력할 수 있다.

 


결과 출력

 

 

 

 

 

 

 

출처 : 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges

반응형