SQL-запрос, который выбирает только одну повторяющуюся запись на основе самого высокого значения даты в этой записи

#mysql #sql #group-by #greatest-n-per-group #window-functions

#mysql #sql #группировка по #наибольшее число на группу #окно-функции

Вопрос:

У меня есть таблица ниже, в которой указаны сведения о сотруднике, а также «Значение даты», которое представляет собой число, основанное на том, когда сотрудник приступил к работе. Как вы можете видеть, ‘Dave’ сегодня дважды синхронизировался, но я хочу видеть только самые последние часы Дейва (чем больше число, тем более поздние часы)

ID — это столбец в базе данных ’employee’ и ‘clock’, который связывает две базы данных вместе, он уникален для каждого сотрудника.

SQL для таблицы ниже

 SELECT e.name, e.country, e.role, e.age, c.dateValue FROM employee e left join clock c on e.ID = c.ID

   | e.name  | e.country|   e.role   |e.age| c.dateValue | c.ID |
    
   | Dave    | England  | Programmer | 45  |     013     |  1   |
   | Gary    | Scotland | Engineer   | 44  |     033     |  2   |
   | Brian   | USA      | Engineer   | 67  |     042     |  4   |
   | Dave    | England  | Programmer | 45  |     019     |  1   |
   | Lucy    | England  | Sales      | 35  |     033     |  5   |
  

Желаемый результат:

    | e.name  | e.country|   e.role   |e.age| c.dateValue | c.ID |
    
   | Gary    | Scotland | Engineer   | 44  |     033     |  2   |
   | Brian   | USA      | Engineer   | 67  |     042     |  4   |
   | Dave    | England  | Programmer | 45  |     019     |  1   |
   | Lucy    | England  | Sales      | 35  |     033     |  5   |
  

В моем желаемом результате первые часы Дейва не отображаются, поскольку я хочу отобразить только одного из каждого сотрудника, независимо от того, подключались ли они один раз или 100 раз сегодня, я хочу показать только их самые последние часы, где значение c.dateValue является самым высоким, и группировка по e.name

SQL, который я пробовал:

 SELECT e.name, e.country, e.role, e.age, c.dateValue FROM employee e left join clock c on e.ID = c.ID group by e.name where MAX(c.dateValue) AS date 


SELECT e.name, e.country, e.role, e.age, MAX(c.dateValue) AS date FROM employee e left join clock c on e.ID = c.ID group by e.name
  

Для обеих попыток моего SQL выше я получаю сообщение об ошибке: » ’employee.country’ недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY «

Ответ №1:

Вам нужна фильтрация, а не агрегация. Я бы рекомендовал row_number() (доступно только в MySQL 8.0):

 select name, country, role, age, datevalue
from (
    select e.*, c.datevalue, row_number() over(partition by c.datevalue order by e.id desc) rn
    from employee e 
    inner join clock c on e.id = c.id
) t
where rn = 1
  

Комментарии:

1. Я внедрил предоставленный вами код, и теперь я получаю сообщение об ошибке ‘Столбец ‘datevalue’ был указан несколько раз для ‘t’.’