mysql 5.7에서 @Rank 사용하기

자바클린·2023년 10월 16일

간단하지만 간단하지 않은 스토리가 하나 있습니다..
바로 들어가겠습니다

2가지 DB작업이 필요했는데요
(예시)
1. 대표 상품을 갖고 있고, 대표 상품과 최근에 사용한 1개 상품을 제외한 나머지 미사용 처리
2. 대표 상품을 갖고 있지 않고, 최근에 사용한 2개 상품을 제외한 나머지 미사용 처리

어떻게 처리할지 2가지 정도 방안을 찾아봤습니다.

  • ROW_NUMBER()/RANK() OVER(PARTITION x ORDER BY y)같은 윈도우 함수 처리 방식
  • 서브쿼리에 LIMIT을 걸어 처리하는 방식

바로 쿼리를 작성해서 날렸고
네...


버전이...너무 낮아요....MySql 5.7 사용자는 웁니다..우럭...

그래도 다른 방법이 있지 않을까 열심히 구글 선생님께 help 요청을 날렸고
@rank := ?
위 방식이 5.7에서 사용 가능하다는 것을 알게 돼서 그때부터 열심히 삽질을 시작했습니다.

첫번째 DB 작업은 아래처럼 쿼리를 구성했습니다.
1. 대표 상품을 갖고 있는 사용자들을 조회하여 WHERE절 서브 쿼리에 추가
2. 해당 유저들 중 2개이상 상품을 지닌 회원들을 조회
3. @rank 함수를 사용해서 user_seq를 기준으로 먼저 나누고
4. user_seq가 동일하면 last_update_date를 기준으로 역순으로 rank하기

두번째 DB 작업은 위 작업에서 첫번째 순서에 대표 상품을 갖고 있지 않는 사용자들을 조회하는 것으로 수정했습니다.

3, 4번 작업을 쿼리로 보여드리자면 아래와 같습니다.

SELECT user_seq,
       product_id,
       last_update_date,
       @rank := IF(@PT_USER_DEPT = user_seq, @rank + 1, 1) AS rn,
       @PT_USER_DEPT := user_seq,
       @PT_USE_DATE := last_use_date
FROM (...
    ORDER BY a.user_seq, a.last_update_date DESC) AS tmp,
     (SELECT @rank := 1, @PT_USER_DATE := '', @PT_USER_DEPT := '') t

@PT_USER_DEPT로 먼저 나누고 같은 값일때는
@PT_USE_DATE가 두번째 기준이 되어 rank 할 수 있었습니다.
역순으로 할지 순서대로 할지는 ORDER BY 문에서 처리하면 될 듯 합니다.

profile
재미있고 고통스러운 개발 공부

0개의 댓글