【问题标题】:Defining the order that distinct items are listed in定义不同项目的列出顺序
【发布时间】:2012-02-05 13:34:30
【问题描述】:

我正在尝试构建一个简单的网站来比较一些人的最佳比赛时间,但是,我在使用 distinct 时遇到了很多困难,这似乎给我带来了一些意想不到的问题。 ..

我有两个数据库 - ResultAthlete(运动员有很多结果)

我正在尝试确定每位运动员参加特定赛事的最快时间,然后将它们按顺序排列。为了做到这一点,我需要创建一个唯一运动员姓名的列表,但它们也必须按时间增加的顺序排列(即更慢)。我目前正在使用:

 <% @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 %>

【问题讨论】:

  • 一个运动员可以有多个performance_times吗?
  • 是的,抱歉,我没有说清楚。如果我为每位运动员提供一次表演,则代码可以正常工作。当一名运动员有两个或更多结果时,问题就出现了
  • 您尚未命名您的数据库系统。我的答案几乎适用于任何 RDBMS,但我使用 PostgreSQL 进行了测试。关于 time 的链接也适用于 PostgreSQL。在 MySQL 和其他人中有一个 time type

标签: sql ruby-on-rails ruby-on-rails-3 distinct


【解决方案1】:

我会使用data type time 中的一列performance_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 只是根据每组重复项的排序顺序获取 first 行。要使用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 的结果放入子选择中,并在附加步骤中按时间排序。

【讨论】:

    猜你喜欢
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 2015-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多