Как сгруппировать таблицу по идентификатору пользователя и получить максимум для другого столбца? - PullRequest
1 голос
/ 18 марта 2020

У меня есть таблица (таблица scrom_scoes_track в bitnami moodle), которая включает в себя столбцы идентификаторов пользователей и значений. Структура таблицы следующая:

Table Structure

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

SELECT 
   `userid`,
   `value`
FROM 
  `mdl_scorm_scoes_track` 
WHERE 
  `element`= 'cmi.core.score.raw' 

Результат вышеприведенного запроса следующий. Query result 1

Но когда я попытался получить максимальное значение, используя следующий запрос, он не работал должным образом.

SELECT 
   `userid`,
   MAX(`value`) 
FROM 
   `mdl_scorm_scoes_track` 
WHERE 
   `element`= 'cmi.core.score.raw' 
GROUP BY 
   `userid` 

Результат запроса выше. Query result 2

Здесь первая строка - идентификатор пользователя 2 и значение 50. Но максимальное значение для идентификатора пользователя 2 должно быть 100. (Как показано на втором изображении). Любая помощь по этой проблеме высоко ценится.

Ответы [ 6 ]

2 голосов
/ 18 марта 2020

Не используйте longtext для числового поля c. альтернативно используйте ниже

SELECT `userid`,MAX(cast(`value` as unsigned)) FROM `mdl_scorm_scoes_track` WHERE `element`= 'cmi.core.score.raw' GROUP BY `userid` 
1 голос
/ 18 марта 2020

У вас правильная идея, но value хранится как longtext, поэтому при применении к нему max вы получите "наибольшее" значение путем лексикографического порядка. Приведение его к целому числу должно решить проблему:

SELECT   `userid`,MAX(CAST(`value` AS UNSIGNED))
FROM     `mdl_scorm_scoes_track`
WHERE    `element`= 'cmi.core.score.raw'
GROUP BY `userid` 
1 голос
/ 18 марта 2020

Сначала вам нужно преобразовать вашу строку в число. В противном случае max() сортирует по алфавиту

SELECT userid, max(cast(value as unsigned))
FROM mdl_scorm_scoes_track 
WHERE element = 'cmi.core.score.raw'
group by userid
0 голосов
/ 18 марта 2020

Правильное решение - преобразовать в число. Однако это тот случай, когда я предпочитаю неявное преобразование, а не явное преобразование:

SELECT userid, max(value + 0)
FROM mdl_scorm_scoes_track 
WHERE element = 'cmi.core.score.raw'
GROUP BY userid;

Это должно работать для любого типа чисел - в частности, отрицательных чисел и чисел с десятичными точками.

0 голосов
/ 18 марта 2020

Вы можете сделать это без оператора GROUP BY. Просто перечислите все строки как обычно, но выберите только максимальное значение из второй копии таблицы. Затем свяжите 2 копии вместе.

SELECT 
   `userid`,
   `value`
FROM 
  `mdl_scorm_scoes_track` as outer
WHERE 
  `element`= 'cmi.core.score.raw' 
  and `value` = (
        select 
           max(`value`) 
        from 
          `mdl_scorm_scoes_track` as inner 
        where 
          inner.userid = outer.userid )
0 голосов
/ 18 марта 2020

Я предполагаю, что столбец значений не является числовым c полем

Попробуйте преобразовать поле значения, например CAST(value AS UNSIGNED)

...