프로그래머스에서 제공하는 SQL문제 매일 풀기 챌린지
2021 Dev-Matching:웹 백엔드 개발자(상반기) 문제
문제 설명
PLACES 테이블은 공간 임대 서비스에 등록된 공간의 정보를 담은 테이블입니다. PLACES 테이블의 구조는 다음과 같으며 ID, NAME, HOST_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
'SQL 문제 풀기 > 1. 프로그래머스 SQL : 2023.12.17~2024.2.29' 카테고리의 다른 글
<프로그래머스 61> 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기(Lv.3) (0) | 2024.02.15 |
---|---|
<프로그래머스 60> 조회수가 가장 많은 중고거래 게시판의 첨부파일 조회하기(Lv.3) (2) | 2024.02.14 |
<프로그래머스 58> 자동차 대여 기록에서 대여중/대여 가능 여부 구분하기(Lv3.) (2) | 2024.02.12 |
<프로그래머스 57> 조건에 맞는 사용자 정보 조회하기(Lv.3) (2) | 2024.02.11 |
<프로그래머스 56> 없어진 기록 찾기(Lv.3) (2) | 2024.02.10 |