0

アスリートの 100 メートルと 200 メートルのレース時間を一覧表示するテーブルからデータを取得する SQL クエリがあります。クエリは、 に基づいて各選手のベスト レース タイムのみを取得します。athlete_idまた、レース タイムが 100 メートル タイムか 200 メートル タイムか ( event_code) も知りたいと考えています。

したがって、ランナーは複数のレース タイムを持つことができますが、クエリは各イベントで各ランナーから最高のレース タイムのみを取得します。

問題は、アスリートがまったく同じベスト レース タイムを 2 回以上行った場合、クエリはそれらすべてのレース タイムを取得することです。クエリが 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
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 が必要です。

ただし、アイデアは単純です。サブクエリのレイヤーがもう 1 つ必要なだけです。

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

ゴードンのものとほぼ同様のアプローチですが、最も早いイベントを使用して関係を断ち切ります (それが何でresult_idあるかは 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 に答える