복붙노트

[SQL] MySQL의 순위 그룹화 수행하는 방법

SQL

MySQL의 순위 그룹화 수행하는 방법

나는 테이블이 그래서 다음과 같이 :

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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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;
    

    어떤 생각이 더 나은 무엇입니까?

  6. from https://stackoverflow.com/questions/532878/how-to-perform-grouped-ranking-in-mysql by cc-by-sa and MIT license