mysql 그룹 별 우선순위 조회 질문드립니다. 0 5 391

by cellion [MySQL] [2021.12.03 15:57:01]


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

 

도움 부탁드립니다.

by 마농 [2021.12.06 08:18:04]

row_number 로 잘 하신 듯 한데 다른 방식을 찾는 이유가 있나요?
설명은 좀 잘못된 듯 하네요.
- "nation이 존재함" 이 아니라 "nation이 KR" 인 듯 하네요.
그리고 정렬기준이 중복될 가능성이 있는 듯 한데요.
- 중복되지 않도록 유니크한 정렬기준을 추가할 필요가 있습니다.


by cellion [2021.12.08 16:45:11]

존재한다는게 특정값으로 존재한다 = 결국 예시에선 KR 이라 말씀하신게 맞습니다.


by 마농 [2021.12.06 11:20:06]

다시 보니 우선순위가 중복될 경우 틀린 결과가 나올 수 있네요.
예를들어 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
;

 


by cellion [2021.12.08 16:47:40]

T,F때문에 case 하나 더 넣는게 더 성능에 안좋나요? 명시적으로 하는게 좋을거 같아서요

seq는 생각 못했네요 감사합니다.


by 마농 [2021.12.08 19:35:57]

함수 사용 하나 정도로 큰 성능 차이가 나지는 않습니다.
불필요한 함수 사용은 줄이는게 맞지만.
명시적 표현이 더 중요한 경우라면 CASE 문 사용하는 게 맞겠지요.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입