with aa as ( select 1 as seq, 'aa' product, 'US' as nation, 'T' as mainFlag union all select 2 as seq, 'aa' product, 'JP' as nation, 'F' as mainFlag union all select 3 as seq, 'aa' product, 'KR' as nation, 'F' as mainFlag union all select 4 as seq, 'bb' product, 'US' as nation, 'F' as mainFlag union all select 5 as seq, 'bb' product, 'JP' as nation, 'T' as mainFlag union all select 6 as seq, 'cc' product, 'US' as nation, 'T' as mainFlag ) select * from aa;
이런 테이블에서 값을 조회 하려고 합니다.
각 product 별로 1 row씩 필요하고 아래 우선순위에 따라 값이 조회 되어야 합니다.
1. nation이 존재함
2. mainFlag 가 T
결과적으로 아래 처럼 데이터가 나오게 하고 싶습니다.
seq product nation mainFlag
3 aa KR F < nation 이 KR
5 bb JP T < nation이 없고 mainFlag T
6 cc US T< nation이 없고 mainFlag T
ROW_NUMBER 써서는 이런식으로 하면 나오긴 하는데 다른 방법이 있을까요?
select * from ( select seq, product, nation, mainFlag, ROW_NUMBER() OVER(PARTITION by product ORDER BY (CASE WHEN nation = 'KR' THEN 0 when mainFlag ='T' then 1 else 2 END)) r from aa) a where r= 1
도움 부탁드립니다.
다시 보니 우선순위가 중복될 경우 틀린 결과가 나올 수 있네요.
예를들어 KR 이 2건 존재하는데, 이 두개 KR의 플래그가 서로 다른 경우
T 가 우선으로 나오게 만드는 정렬 조건이 아니네요.
수정이 필요합니다.
- Case 문을 각각 분리
- 다만, 플래그가 T / F 두가지 뿐이라면 굳이 Case 사용 안해도 됩니다.
- 최종 유니크 정렬 추가
SELECT * FROM (SELECT seq, product, nation, mainFlag , ROW_NUMBER() OVER(PARTITION BY product ORDER BY CASE WHEN nation = 'KR' THEN 1 ELSE 2 END , CASE WHEN mainFlag = 'T' THEN 1 ELSE 2 END , seq ) r FROM aa ) a WHERE r = 1 ;
SELECT * FROM (SELECT seq, product, nation, mainFlag , ROW_NUMBER() OVER(PARTITION BY product ORDER BY CASE WHEN nation = 'KR' THEN 1 ELSE 2 END , mainFlag DESC , seq ) r FROM aa ) a WHERE r = 1 ;