MySQL SUM TOP 2 записей по каждой категории - PullRequest
1 голос
/ 19 мая 2019

У меня есть таблица с оценками студентов, я пытаюсь суммировать 2 верхние оценки по всем студентам для определенной категории. У меня есть поиск похожих сообщений, но я не получил правильный ответ

Я попытался суммировать оценки, но получаю результат только для двух учеников, а не для всех, и это не дает мне правильного значения.

SELECT SUM(marks) as totalmarks,stdid 
   FROM (( select marks,stdid 
               from finalresult 
               where `subjectcategory` = 1 
                    AND `classId`='3' AND `year`='2018'  
                    AND `term`='2' AND `type`='23' 
               order by marks  desc 
               LIMIT 2 ))t1  
   GROUP BY stdid

Ответы [ 2 ]

0 голосов
/ 19 мая 2019

В MySQL 8+ вы должны сделать:

SELECT stdid, SUM(marks) as totalmarks
FROM (SELECT fr.*,
             ROW_NUMBER() OVER (PARTITION BY stdid ORDER BY marks DESC) as seqnm
      FROM finalresult fr
      WHERE subjectcategory = 1 AND 
            classId = 3 AND 
            year = 2018 AND  
            term = 2 AND
            type = 23 
     ) fr
WHERE seqnum <= 2
GROUP BY stdid;

Обратите внимание, что я удалил одинарные кавычки.Вещи, которые выглядят как числа, вероятно, есть.И вы не должны смешивать тип - поместите кавычки обратно, если значения действительно хранятся в виде строк.

В более ранних версиях, вероятно, самый простой способ - использовать переменные, но вы должны быть очень осторожны с ними.MySQL не гарантирует порядок вычисления переменных в SELECT, поэтому вы не можете назначить переменную в одном выражении и использовать ее в другом.

Сложное выражение решает это.Кроме того, лучше всего выполнить сортировку в подзапросе (последние версии MySQL 5+ требуют этого):

SELECT stdid, SUM(marks) as totalmarks
FROM (SELECT fr.*,
             (@rn := IF(@s = stdid, @rn + 1,
                        IF(@s := stdid, 1, 1)
                       )
             ) as seqnum
      FROM (SELECT fr.*
            FROM finalresult fr
            WHERE subjectcategory = 1 AND 
                  classId = 3 AND 
                  year = 2018 AND  
                  term = 2 AND
                  type = 23 
            ORDER BY stdid, marks DESC
           ) fr CROSS JOIN
           (SELECT @s = '', @rn := 0) params
WHERE seqnum <= 2
GROUP BY stdid;
0 голосов
/ 19 мая 2019

Вспомогательный подзапрос может использоваться для итерации

    SELECT
        stdid, marks
    FROM
    (
        SELECT stdid, marks,
               @rn := IF(@iter = stdid, @rn + 1, 1) AS rn,
               @iter := stdid
         FROM finalresult
         JOIN (SELECT @iter := NULL, @rn := 0) AS q_iter
        WHERE `subjectcategory` = 1 
          AND `classId`='3' 
          AND `year`='2018'  
          AND `term`='2' 
          AND `type`='23'  
        ORDER BY stdid, marks DESC
    ) AS T1
    WHERE rn <= 2

это решение игнорирует связи и использует только два для каждого идентификатора студента.

Демо

...