MySQL의 번들 스키마 sakila의 film을 이용한다
SELECT title, length FROM sakila.film;
랭킹 매기기 (공동순위 X)
영화의 길이로 랭킹을 매길 것이다.
SELECT title, length, @curRank := @curRank + 1 AS rank
FROM film f, (SELECT @curRank := 0) r
ORDER BY length desc;
해석 :
FROM 절의 인라인 서브쿼리 SELECT문은 변수를 생성하기 위해서 부른 것이다.
curRank를 0으로 초기화 해서 불렀다.
서브쿼리는 r 같은 별칭을 달아줘야한다.
본 쿼리에서 SELECT문에서 length를 호출하는 순간 ORDER BY가 호출되는 듯 하다.
( 내 임의로 생각한 예측임- 그러지 않으면 랭킹이 매겨질 수 없다.)
그리고 3번째 컬럼 @curRank := @curRank + 1 AS rank
curRank변수에 1을 더하고 (0+1), 컬럼명을 rank로 한다.
테이블이 끝날 때까지 반복
결과
랭킹 매기기 (공동순위 O)
같은 길이의 영화는 같은 랭킹이 되도록 할 것이다.
SELECT
title,
length,
if(length < @prevLength, if(length = (@prevLength := length), @curRank := @curRank + 1, 0), @curRank) AS rank
FROM film f, (SELECT @curRank := 0, @prevLength := 9999) r
ORDER BY length desc;
해석 :
FROM 절의 인라인 서브쿼리 SELECT문은 변수를 생성하기 위해서 부른 것이다.
curRank를 0으로 초기화 해서 불렀다.
prevLength를 9999로 초기화 해서 불렀다.
서브쿼리는 r 같은 별칭을 달아줘야한다.
본 쿼리에서 SELECT문에서 length를 호출하는 순간 ORDER BY가 호출되는 듯 하다.
( 내 임의로 생각한 예측임- 그러지 않으면 랭킹이 매겨질 수 없다.)
3번째 컬럼에 조건문을 건다.
조건문의 구조는 IF( 조건, 조건이 true일 때 실행, 조건이 false 일 때 실행 ) 이다.
현재 행의 length가 prevLength보다 작다면 true이기 때문에 2번째 칸의 코드를 실행한다.
( if(length = (@prevLength := length), @curRank := @curRank + 1, 0) )
난해할 수 있지만 이렇게 만든 이유가 있다.
조건은 (length < @prevLength) 이미 달성되었지만 남은 숙제가 있다.
prevLength 값을 현재 length로 바꿔줘야하는데 출력은 또 rank로 해줘야하는 것이다.
일단 첫번째 칸인 조건 -> length = (@prevLength := length)
@prevLength := length로 현재 length로 바꿔주고 length 와 비교하는 조건문을 만들었다. 무조건 true가 떨어진다.
그 후 true 실행문인 @curRank := @curRank + 1 를 실행한다. 즉, 증가된 숫자로 바꾼뒤 출력한다. (0 -> 1)
반대로 현재 행의 length가 prevLength와 같다면 false가 되서 curRank 즉, 증가되지 않은 수치가 출력된다.
테이블이 끝날 때까지 반복
'Database > MySQL' 카테고리의 다른 글
mysql // 피벗 테이블 (0) | 2020.09.09 |
---|---|
MYSQL 다운로드 (0) | 2020.07.07 |
mySQL 테이블 ddl 확인 (0) | 2020.06.26 |
mySQL 에서 날짜 이용하기/ 더하기 빼기 (0) | 2020.06.26 |
mysql 외래키 foreign key 설정 (0) | 2020.06.24 |