[SQL] MySQL의 순위 그룹화 수행하는 방법
SQLMySQL의 순위 그룹화 수행하는 방법
나는 테이블이 그래서 다음과 같이 :
ID_STUDENT | ID_CLASS | GRADE
-----------------------------
1 | 1 | 90
1 | 2 | 80
2 | 1 | 99
3 | 1 | 80
4 | 1 | 70
5 | 2 | 78
6 | 2 | 90
6 | 3 | 50
7 | 3 | 90
나는 그 그룹 정렬 그들을 제공하기 위해 필요 :
ID_STUDENT | ID_CLASS | GRADE | RANK
------------------------------------
2 | 1 | 99 | 1
1 | 1 | 90 | 2
3 | 1 | 80 | 3
4 | 1 | 70 | 4
6 | 2 | 90 | 1
1 | 2 | 80 | 2
5 | 2 | 78 | 3
7 | 3 | 90 | 1
6 | 3 | 50 | 2
지금 나는 당신이 여기 같은 순위에 임시 변수를 사용할 수 있다는 것을 알고,하지만 난 그것을 그룹화 세트에 대해 어떻게해야합니까? 어떤 통찰력을 주셔서 감사합니다!
해결법
-
==============================
1.
SELECT id_student, id_class, grade, @student:=CASE WHEN @class <> id_class THEN 0 ELSE @student+1 END AS rn, @class:=id_class AS clset FROM (SELECT @student:= -1) s, (SELECT @class:= -1) c, (SELECT * FROM mytable ORDER BY id_class, id_student ) t
이것은 매우 일반 방식으로 작동합니다 :
-
==============================
2.(가장 좋은 대답으로 표시) Quassnoi의 솔루션에 문제가 있습니다.
(가장 좋은 대답으로 표시) Quassnoi의 솔루션에 문제가 있습니다.
I는 (즉, 가상적인 MySQL은 SQL 윈도우 함수)와 동일한 문제를 가지고 이전 I 행 값을 저장하기 위해 사용자 정의 된 변수를 사용하여, Quassnoi의 솔루션을 구현하는 데 사용 ...
그러나, MySQL의 업그레이드 또는 무엇 이건, 내 쿼리가 더 이상 작동하지 않았다 어쩌면 후. SELECT의 필드의 평가 순서가 보장되지 않기 때문입니다. @class 할당은이 SELECT의 뒤에 위치하는 경우에도, @student 할당하기 전에 평가 될 수있다.
이것은 다음과 같이 MySQL의 문서에서 언급 한 :
출처 : http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
마지막으로 나는 그것을 읽은 후 할당 @class를 확인하기 위해 그런 트릭을 사용하고 있습니다 :
SELECT id_student, id_class, grade, @student:=CASE WHEN @class <> id_class THEN concat(left(@class:=id_class, 0), 0) ELSE @student+1 END AS rn FROM (SELECT @student:= -1) s, (SELECT @class:= -1) c, (SELECT * FROM mytable ORDER BY id_class, grade desc ) t
좌측 () 함수를 사용하는 것은 단지 세트 @class 변수에 사용된다. 그 다음, 결과를 연결할 왼쪽 ()는 예상 된 결과에 투명 (NULL 같음).
아니 매우 우아하지만 작품!
-
==============================
3.
SELECT g1.student_id , g1.class_id , g1.grade , COUNT(*) AS rank FROM grades AS g1 JOIN grades AS g2 ON (g2.grade, g2.student_id) >= (g1.grade, g1.student_id) AND g1.class_id = g2.class_id GROUP BY g1.student_id , g1.class_id , g1.grade ORDER BY g1.class_id , rank ;
결과:
+------------+----------+-------+------+ | student_id | class_id | grade | rank | +------------+----------+-------+------+ | 2 | 1 | 99 | 1 | | 1 | 1 | 90 | 2 | | 3 | 1 | 80 | 3 | | 4 | 1 | 70 | 4 | | 6 | 2 | 90 | 1 | | 1 | 2 | 80 | 2 | | 5 | 2 | 78 | 3 | | 7 | 3 | 90 | 1 | | 6 | 3 | 50 | 2 | +------------+----------+-------+------+
-
==============================
4.위의 수정이 작동하지만 나는 그것을 할 필요가 생각하는 것보다 더 복잡합니다 :
위의 수정이 작동하지만 나는 그것을 할 필요가 생각하는 것보다 더 복잡합니다 :
SELECT ID_STUDENT, ID_CLASS, GRADE, RANK FROM (SELECT ID_STUDENT, ID_CLASS, GRADE, @student:=CASE WHEN @class <> id_class THEN 1 ELSE @student+1 END AS RANK, @class:=id_class AS CLASS FROM (SELECT @student:= 0) AS s, (SELECT @class:= 0) AS c, (SELECT * FROM Students ORDER BY ID_CLASS, GRADE DESC ) AS temp ) AS temp2
-
==============================
5.나는 약간의 검색을 한이 솔루션을 마련하기 위해이 문서를 발견 :
나는 약간의 검색을 한이 솔루션을 마련하기 위해이 문서를 발견 :
SELECT S2.*, FIND_IN_SET( S2.GRADE , ( SELECT GROUP_CONCAT(GRADE ORDER BY GRADE DESC) FROM Students S1 WHERE S1.ID_CLASS = S2.ID_CLASS ) ) AS RANK FROM Students S2 ORDER BY ID_CLASS, GRADE DESC;
어떤 생각이 더 나은 무엇입니까?
from https://stackoverflow.com/questions/532878/how-to-perform-grouped-ranking-in-mysql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] LISTAGG 기능 : "문자열 연결의 결과가 너무 깁니다" (0) | 2020.03.17 |
---|---|
[SQL] MySQL의 외래 키 제약 조건은 잘못 오류가 형성된다 (0) | 2020.03.17 |
[SQL] VARCHAR에 대한 장점은 (500)를 통해 VARCHAR (8000)가있다? (0) | 2020.03.17 |
[SQL] 재귀는 자체 조인 할 수있는 가장 간단한 방법은? (0) | 2020.03.17 |
[SQL] SELECT와 INSERT (0) | 2020.03.17 |