0

我有一个 SQL 查询,它从列出运动员 100 米和 200 米比赛时间的表中检索数据。该查询仅根据 检索每个运动员的最佳比赛时间athlete_id,它还想知道比赛时间是 100 米还是 200 米时间 ( event_code)。

因此,跑步者可以有多个比赛时间,但查询只能从每个比赛中的每个跑步者那里获得最佳比赛时间。

问题是,如果运动员两次或多次完成完全相同的最佳比赛时间,则查询会检索所有这些比赛时间。如何确保查询只检索一个值?

这是代码:

select r.*
from result r
inner join (
    select athelete_id, min(result_time) as FastestTime
    from result
    where event_code = 1
    group by athelete_id
) rm on r.athelete_id = rm.athelete_id and r.result_time = rm.FastestTime
4

3 回答 3

1

抱歉,我有点误解了这个问题,但你可以像这样为所有竞争对手管理它:

 select MIN(r.id), r.athelete_id, r.result_time, r....
    from result r
    inner join (
        select athelete_id, min(result_time) as FastestTime
        from result
        where event_code = 1
        group by athelete_id
    ) rm on r.athelete_id = rm.athelete_id and r.result_time = rm.FastestTime
    GROUP BY r.athelete_id, r.result_time, r.... 
--(as how many column you have, except r.ID)

试试这个:

select top 1 r.*
from result r
inner join (
    select athelete_id, min(result_time) as FastestTime
    from result
    where event_code = 1
    group by athelete_id
) rm on r.athelete_id = rm.athelete_id and r.result_time = rm.FastestTime

或者

SET ROWCOUNT 1

    select r.*
    from result r
    inner join (
        select athelete_id, min(result_time) as FastestTime
        from result
        where event_code = 1
        group by athelete_id
    ) rm on r.athelete_id = rm.athelete_id and r.result_time = rm.FastestTime
于 2012-08-29T19:38:26.113 回答
1

这在 SQL Server 2000 中很痛苦。使用 row_number 会容易得多,但这需要 2005。

然而,这个想法很简单,你只需要多一层子查询:

select r.*
from result r join
     (select r.athelete_id, MIN(result_id) as minresult_id
      from result r inner join
           (select athelete_id, min(result_time) as FastestTime
            from result
            where event_code = 1
            group by athelete_id
           ) rm
           on r.athelete_id = rm.athelete_id and r.result_time = rm.FastestTime
      group by r.athelete_id
     ) aft
     on r.result_id = minresult_id

最里面的子查询基本上是您的子查询。然后,通过 athelete_id 聚合,得到最小的 result_id,用于最终的连接。

于 2012-08-29T19:54:06.593 回答
0

很大程度上与 Gordon 的方法类似,但使用最早的事件来打破平局(这应该是身份列,如果是这样的话result_id,但这并不总是得到保证)。

DECLARE @event_code INT;
SET @event_code = 1;

SELECT r.*
FROM dbo.result AS r 
INNER JOIN 
(
  SELECT r2.athelete_id, x.mintime, mindate = MIN(r2.result_date)
    FROM 
    (
      SELECT athelete_id, mintime = MIN(result_time)
      FROM dbo.result
      WHERE event_code = @event_code
      GROUP BY athelete_id
    ) AS x
    INNER JOIN dbo.result AS r2
    ON x.athelete_id = r2.athelete_id
    AND x.mintime = r2.result_time
    WHERE r2.event_code = @event_code
    GROUP BY r2.athelete_id, x.mintime
) AS y
ON r.athelete_id = y.athelete_id
AND r.result_time = y.mintime
AND r.result_date = y.mindate
WHERE r.event_code = @event_code;

当然,在 SQL Server 2005 中要容易得多:

;WITH x AS 
(
  SELECT athelete_id, --... other columns, 
    rn = ROW_NUMBER() OVER (PARTITION BY athelete_id ORDER BY result_time, result_date)
  FROM dbo.result
  WHERE event_code = 1
)
SELECT athelete_id, --... other columns
FROM x WHERE rn = 1;
于 2012-08-29T20:13:11.120 回答