Определение порядка, в котором отдельные элементы перечислены в - PullRequest
0 голосов
/ 05 февраля 2012

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

У меня есть две базы данных - Result и Athlete (у спортсмена много результатов)

Я пытаюсь определить самое быстрое время для каждого спортсмена для конкретного события, а затем привести их в порядок. Для этого мне нужно создать список уникальных имен спортсменов, НО они также должны быть в порядке увеличения времени (т.е. медленнее). Я сейчас использую:

 <% @filtered_names = Result.where(:event_name => params[:justevent]).joins(:athlete).order('performance_time_hours ASC').order('performance_time_mins ASC').order('performance_time_secs ASC').order('performance_time_msecs ASC').select('distinct athlete_id') %>

Это, похоже, работает, однако я обнаружил, что если последняя запись в базе данных results самая медленная среди всех спортсменов, этот спортсмен попадает в конец моего списка имен, ДАЖЕ ЕСЛИ один из их предыдущие результаты - самые быстрые за все время!

Может кто-нибудь сказать мне, работает ли distinct каким-то странным образом и как я могу обойти эту проблему? Если нижний результат самый быстрый, скрипт работает без ошибок ...

Ради полноты мне нужна эта информация для запуска следующего кода:

 <% @filtered_names.each do |filtered_name| %>
 <% @currentathleteperformance = Result.where(:event_name => params[:justevent]).where(:athlete_id => filtered_name.athlete_id).order('performance_time_hours ASC').order('performance_time_mins ASC').order('performance_time_secs ASC').order('performance_time_msecs ASC').first() %>
 <% @currentathlete = Athlete.where(:id => filtered_name.athlete_id).first() %>

    <td><%= @currentathleteperformance.performance_time_mins %>:<%= @currentathleteperformance.performance_time_secs %>:<%= @currentathleteperformance.performance_time_msecs %> </td>
    <td><%= @currentathleteperformance.wind_speed %></td>
    <td><%= @currentathleteperformance.athlete_name %></td>
    <td><%= @currentathlete.gender %></td>
    <td><%= @currentathlete.sec %></td>
    <td><%= @currentathleteperformance.competition_name %></td>
    <td><%= @currentathleteperformance.round %></td>
    <td><%= @currentathleteperformance.position %></td>
    <td><%= @currentathleteperformance.performance_date %></td>
    <td><%= @currentathlete.coach_name %></td>
<% end %>

1 Ответ

0 голосов
/ 05 февраля 2012

Я бы использовал 1 столбец performance_time из тип данных time, чтобы заменить все:

performance_time_hours
performance_time_mins
performance_time_secs
performance_time_msecs

или interval, если для одного выступления более 24 часоввозможно.

Я не очень хорошо разбираюсь в синтаксисе Ruby, но запрос, чтобы получить то, что вы хотите, может выглядеть следующим образом - при условии, что спортсмены могут выступать несколько раз за событие, а event_name уникален:

SELECT athlete_id, min(performance_time) AS min_performance_time
FROM   result
WHERE  event_name = params[:justevent]
GROUP  BY athlete_id
ORDER  BY min(performance_time), athlete_id

Кроме того, я приказываю на athlete_id, но это просто произвольная мера для стабильного разрыва связей.

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

SELECT athlete_id, performance_time
FROM (
    SELECT DISTINCT ON (athlete_id)
           athlete_id, performance_time
    FROM   result
    WHERE  event_name = params[:justevent]
    ORDER  BY athlete_id, performance_time
    ) a
ORDER BY performance_time, athlete_id

Вам нужно ORDER BY athlete_id, чтобы получить отдельных спортсменов, и вы не можете сначала сделать заказ как минимум на performance_time на том же уровне запросов.Поэтому вам нужно поместить результат SELECT DISTINCT в подвыбор и отсортировать по времени в дополнительном шаге.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...