计算两行之间的时差

时间:2019-07-02 14:38:12

标签: sql sql-server-2012

我有一张桌子,上面有关于已经举行的比赛的信息,它容纳了参加比赛的人,他们在比赛中的完成时间以及什么时候结束。我想添加一个时差列,该列显示每个参与者落后于获胜者多远。

Race ID   Finish place     Time         Name
   1             1        00:00:10      Matt
   1             2        00:00:11      Mick
   1             3        00:00:17      Shaun
   2             1        00:00:13      Claire
   2             2        00:00:15      Helen

我想看的

Race ID   Finish place     Time       Time Dif   Name
   1             1        00:00:10               Matt
   1             2        00:00:11    00:00:01   Mick
   1             3        00:00:17    00:00:07   Shaun
   2             1        00:00:13               Claire
   2             2        00:00:15    00:00:02   Helen

我看到过类似的问题,但我无法将其与我的问题联系起来。
我最初的想法是拥有一些派生表,这些派生表按完成位置过滤掉,但可能会有10个以上的赛车手,因此事情开始变得混乱。我正在使用Management Studio 2012

3 个答案:

答案 0 :(得分:2)

您可以将min()用作窗口函数:

select t.*,
       (case when time <> min_time then time - min_time
        end) as diff
from (select t.*, min(t.time) over (partition by t.race_id) as min_time
      from t
     ) t

我更倾向于将其表示为秒:

       (case when time <> min_time then datediff(second, min_time, time)
        end) as diff

答案 1 :(得分:1)

使用http://www.convertcsv.com/csv-to-sql.htm构建示例数据:

DROP TABLE IF EXISTS mytable

CREATE TABLE mytable(
   Race_ID      INTEGER 
  ,Finish_place INTEGER 
  ,Time         VARCHAR(30)
  ,Name         VARCHAR(30)
);
INSERT INTO mytable(Race_ID,Finish_place,Time,Name) VALUES (1, 1,'00:00:10','Matt');
INSERT INTO mytable(Race_ID,Finish_place,Time,Name) VALUES (1, 2,'00:00:11','Mick');
INSERT INTO mytable(Race_ID,Finish_place,Time,Name) VALUES (1, 3,'00:00:17','Shaun');
INSERT INTO mytable(Race_ID,Finish_place,Time,Name) VALUES (2, 1,'00:00:13','Claire');
INSERT INTO mytable(Race_ID,Finish_place,Time,Name) VALUES (2, 2,'00:00:15','Helen');

仅排名第一的CTE会更容易理解。

WITH CTE_FIRST
AS (
    SELECT
        M.Race_ID
       ,M.Finish_place
       ,M.Time
       ,M.Name
    FROM mytable M
    WHERE M.Finish_place = 1
)
SELECT
        M.Race_ID
       ,M.Finish_place
       ,M.Time
       ,CASE
            WHEN m.Finish_place = 1
                THEN NULL
            ELSE CONVERT(VARCHAR, DATEADD(ss, DATEDIFF(SECOND, c.Time, M.Time), 0), 108)
        END AS [Time Dif]
       ,M.Name
    FROM mytable M
    INNER JOIN CTE_FIRST c
        ON M.Race_ID = c.Race_ID

答案 2 :(得分:0)

您可以使用窗口功能。 MIN([time]) OVER (PARTITION BY race_id ORDER BY finish_place)给出同一种族中第一行的时间值。 DATEDIFF(SECOND, (MIN([time]) OVER (PARTITION BY race_id ORDER BY finish_place)), time)带来了不同。