docker run -d -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=true --name mysql mysql:5.7
//도커로 mysql:5.7을 백그라운드로 실행하는데
//포트 포워딩으로 호스트의 3306이랑 도커의 3306이랑 연결
//mysql5.7실행 시 필요한 설정을 -e옵션으로 주고
//이름을 mysql로 설정(아니면 랜덤)
docker pull ubuntu:16.04 //down
docker images | grep 16.04 //검색
docker run ubuntu:16.04 //실행 but 바로 종료
docker ps // 도커 컨테이너 실행중인것 확인
docker container ls -a //전체 히스토리 확인
docker container rm 컨테이너ID //컨테이너 삭제
2024-02-08 15:54:27.567 INFO [order-service,89bf1666da761e42,730648c3fe5dad8a] 4968 --- [o-auto-1-exec-4] c.e.o.controller.OrderController : before get orders
Hibernate: select order0_.id as id1_0_, order0_.created_at as created_2_0_, order0_.order_id as order_id3_0_, order0_.product_id as product_4_0_, order0_.qty as qty5_0_, order0_.total_price as total_pr6_0_, order0_.unit_price as unit_pri7_0_, order0_.user_id as user_id8_0_ from orders order0_ where order0_.user_id=?
2024-02-08 15:54:28.069 INFO [order-service,89bf1666da761e42,730648c3fe5dad8a] 4968 --- [o-auto-1-exec-4] c.e.o.controller.OrderController : after call orders msa
select (@rank := @rank +1) as ranking,
hutw.*
from user_stat_weekly hutw, (select @rank := 0) as ranking
where hutw.start_date ='2024-02-05'
order by hutw.prize_total desc
@를 사용한 사용자 변수는 native query를 사용해야 한다.
허나 그냥 사용하면 아래와 같은 에러가 발생한다.
Caused by: org.hibernate.QueryException: Space is not allowed after parameter prefix ':'
:= @rank 이 부분에서 발생하는 것인데, 하이버네이트 버전에 따라 역슬래시를 하나나 두 개 넣어야 한다고 한다.
내가 사용하는 버전에서는 아래처럼 두 개 넣었더니 성공한다.
SELECT (@rank \\:= @rank +1) ...
잘 지나가나 싶어서 실행해 보면 아래 에러가 발생하는데, 해당 에러는 native query 결과를 object에 세팅할 때 class를 매핑해서 나는 것으로 projection interface로 바꾸면 해결된다.
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type
mysql 8버전부터 rank over 함수가 들어오면서 드디어! 편한 함수의 세상이 열리긴 한다만..
아직 5.7을 사용하고 있기에 그 이하 버전에 등수를 구하는 방법을 알아야 한다.
서버에 부하가 가지 않고 제일 좋은 방법은 집계할 때 등수를 같이 쌓아주어 그냥 select 해가면 되는 것이지만..
서버는 그닥 user-friendly 하지 않다. 그리고 기획자는 서버에 없는 것만 요청한다..
1. count 사용 서브쿼리
select * from (
select
(select count(*) +1 from table for_rank where for_rank.start_date ='2023-02-06' and for_rank.prize_total > this.prize_total) as r,
this.*
from table this
where this.start_date ='2023-02-06'
order by prize_total desc
) as with_rank
where id = 'tbot0275'
2. @사용자 정의 변수 사용
select * from (
select (@rank := @rank +1) as r,
this.*
from table this, (select @rank := 0) as ranking
where this.start_date ='2023-02-06'
order by prize_total desc
)as weekly_with_rank
where id = 'tbot0275'
허나 두 쿼리의 결과가 다를 수 있다. 왜냐면 동점자를 다루는 방식이 다르기 때문.
위 이미지에서처럼 1번의 경우 동점자를 같은 등수로 치게 되고 2번의 경우는 어쨌건 한 줄 서기라 조회에 따라 랜덤 하게 등수가 나올 수 있다.