MySQL выбирает лучшие (и самые старые) показатели для каждого спортсмена, категории

0

Я пытаюсь построить SQL-запрос из следующей таблицы (пример):

Пример таблицы с именем "performances"

Это таблица с атлетическими выступлениями. Я хочу выбрать лучший из этой таблицы для каждой дисциплины и набор из одной или нескольких категорий. Каждый спортсмен должен быть только один раз в результате, хотя его лучшая производительность в два раза больше в таблице производительности.

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

На самом деле у меня есть этот SQL-запрос, но из подзапроса объединяются все строки с лучшим значением для athlete_id и лучше всего:

SELECT 

p.athlete_id, p.value 

FROM

(SELECT athlete_id, MAX(value) AS best FROM performances 

WHERE discipline_id = 32 AND category_id IN (1,3,5,7,9) 

GROUP BY athlete_id) f

INNER JOIN performances p 

ON p.athlete_id = f.athlete_id AND p.conversion = f.best

ORDER BY p.value DESC, p.created 

Пожалуйста, как я могу присоединиться только к одной строке для каждого спортсмена, у которого есть самый старый созданный атрибут?

Теги:
join
group-by
greatest-n-per-group

3 ответа

0

Большое вам спасибо, ребята. После ваших ответов я наконец нашел решение.

SELECT r.* FROM 

(SELECT p.athlete_id, p.conversion, MIN(p.created) AS created FROM

(SELECT athlete_id, MAX(conversion) AS best 
FROM performances 
WHERE discipline_id = 32 AND category_id IN (1,3,5,7,9) 
GROUP BY athlete_id) f

INNER JOIN performances p ON p.athlete_id = f.athlete_id AND p.conversion = f.best
GROUP BY p.athlete_id) w INNER JOIN performances r 

ON w.athlete_id = r.athlete_id AND w.conversion = r.conversion 
AND ((w.created = r.created) OR (w.created IS NULL AND r.created IS NULL))

ORDER BY r.conversion DESC, r.created
0

Вам не нужно использовать соединения, вы можете сделать это с помощью оконной функции:

SELECT 
  p.athlete_id, 
  p.value 
FROM 
  (
    SELECT 
      athlete_id, 
      value, 
      ROW_NUMBER() over (partition by athlete_id order by value desc, created) rowid 
    FROM 
      performances 
   WHERE 
      discipline_id = 32 AND 
      category_id IN (1,3,5,7,9) 
  ) p 
where 
  p.rowid = 1
  • 0
    Старые выпуски Mysql не предлагают оконные функции, только новые выпуски от 8+ будут иметь эту функцию
  • 1
    оооо, мне очень жаль, я пропустил тег MySQL ... извините
Показать ещё 2 комментария
0

Чтобы получить одну строку для каждого athlete на discipline на основе наибольшего значения value вы можете сделать себя левым соединение, чтобы обработать случай галстука или одного athlete имеет более чем 1 строки, имеющие одинаковое максимальное значение, которое вы можете использовать случай выражение, чтобы выбрать строку с самой старой датой

select a.*
from performances a
left join performances b
on a.discipline_id = b.discipline_id
and a.athlete_id = b.athlete_id
and case when a.value = b.value
    then a.created > b.created
    else a.value < b.value
    end 
where b.discipline_id is null

DEMO

Далее вы можете добавить фильтр в свой пункт where where

and a.discipline_id = 32 
and a.category_id IN (1,3,5,7,9)

DEMO

  • 0
    Обратите внимание, что это решение плохо масштабируется, но имеет то преимущество, что оно будет работать даже на самой древней версии MySQL.
  • 0
    Большое спасибо, но это решение не работает. Может быть, я не могу объяснить, что именно мне нужно.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню