[PostgreSQL] ROW_NUMBER() OVER PARTITION BY를 이용한 다중 칼럼 그룹핑 조회
쿼리문은 알면 알수록 오묘한 것.
다양한 형태로 내가 원하는대로 데이터를 뽑기 위해서는 마찬가지로 다양한 스킬들을 알고 있어야 한다.
특히 이 row_number() 함수를 이용한 방법은 두고두고 도움이 된다!
개발자는 쿼리를 짤 때 퍼포먼스를 고려한, 성능이 저하되지 않도록 옵티마이징 한다. 혹은 데이터를 분산배치, 마트 테이블을 구성하기도 한다.
마케터는 데이터를 뽑아내기만 하면 된다. 그래서 이런 쿼리를 공부하는게 개발자뿐 아니라 sql을 사용할 마케터에게도 도움이 될 수 있다.
일단 샘플테이블을 만들어 데이터를 넣어준다.
/* 테이블 생성 */
create table sample(
id varchar not null,
name varchar not null,
age int not null,
university varchar
)
/* 샘플데이터 삽입 */
insert into sample values
('1000','밍구1','20','서울대'),
('2000','밍구2','25','고려대'),
('1000','밍구3','25','연세대'),
('3000','밍구4','28','서울대'),
('2000','밍구5','27','연세대'),
('2000','밍구6','30','중앙대'),
('5000','밍구7','30','고려대'),
('4000','밍구8','30','서울대')
;
자 여기서 id가 중복되는 경우도 있고 age나 university 칼럼이 중복되는 경우도 있다.
내가 중복되지 않은 특정컬럼을 뽑아내고자 한다면
동일한 컬럼을 묶어내는 group by와 중복을 제거해서 unique 한 값만을 나타내는 select절의 distinct 조건을 사용하는 방법이 있을 것이다.
그러나 이 방법엔 치명적인 단점이 있는데, 내가 중복 제거한 칼럼 이외의 데이터는 볼 수가 없다는 것이다.
group by 절을 아래와 같이 사용한다면 SQL Error 가 발생한다.
이럴 때 사용하는 방법이 바로 ROW_NUMBER() 함수이다.
이 함수는 내가 보고 싶은 순서대로 정렬을 하고 ROW에 대해 순서를 매기는 기능을 한다.
select *, row_number() over (order by age) from sample;
그럼 단순히 결과를 칼럼 순으로 정렬하는 order by 와 무슨 차이가 있느냐 할 텐데
여기에 PARTITION BY 절을 추가하면 된다.
select *, row_number() over (PARTITION by university order by age desc) from sample;
결론적으로 내가 여기서 row_number 칼럼이 1인 녀석들만 가지고 오면 같은 university의 1명만 가져올 수 있다.
select *
from (
select *, row_number() over (PARTITION by university order by age desc) as rnum from sample
) t
where rnum = 1;
<참고>
https://www.postgresqltutorial.com/postgresql-row_number/
'Database' 카테고리의 다른 글
[MSSQL & SQL Server] Dirty read, WITH (NOLOCK) (0) | 2022.06.09 |
---|---|
[PostgreSQL] 유저 생성, 권한 주기 (0) | 2022.01.05 |
[PostgreSQL] count filter를 이용한 여러건 동시추출 (0) | 2021.11.01 |
[PostgreSQL] 랜덤쿠폰번호 생성 및 중복체크 Function 만들기 (0) | 2021.10.19 |
[PostgreSQL] DB내에 개행과 작은따옴표(') 사용 (0) | 2021.08.24 |