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

+ Recent posts