Я пытаюсь построить 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
Пожалуйста, как я могу присоединиться только к одной строке для каждого спортсмена, у которого есть самый старый созданный атрибут?
Большое вам спасибо, ребята. После ваших ответов я наконец нашел решение.
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
Вам не нужно использовать соединения, вы можете сделать это с помощью оконной функции:
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
Чтобы получить одну строку для каждого 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
Далее вы можете добавить фильтр в свой пункт where where
and a.discipline_id = 32
and a.category_id IN (1,3,5,7,9)