SQL Server:多行的DateDiff之和

SQL Server:多行的DateDiff之和,sql,sql-server,tsql,Sql,Sql Server,Tsql,因此,我有两个表的结构与此类似: Run([RunID]、[PlayerID]、[Score]) 跳转([ID]、[RunID]、[Time]、[Type]) 有4种“类型”的时间2“上升”和2“下降” 我需要在给定的跑步中获得“上升”和“下降”之间的时间 基本上,在进行“跳跃”的“跑步”过程中,我记录一个上升时间,在相应的落地上记录一个下降时间(每次跑步只记录一对)。在“跑步”结束时,我需要显示“在空中”的总时间,以及每次跳跃的时间。我想最好的方法是将数据转储到具有以下结构的临时表中: @

因此,我有两个表的结构与此类似:

  • Run([RunID]、[PlayerID]、[Score])

  • 跳转([ID]、[RunID]、[Time]、[Type])

有4种“类型”的时间2“上升”和2“下降”

我需要在给定的跑步中获得“上升”和“下降”之间的时间

基本上,在进行“跳跃”的“跑步”过程中,我记录一个上升时间,在相应的落地上记录一个下降时间(每次跑步只记录一对)。在“跑步”结束时,我需要显示“在空中”的总时间,以及每次跳跃的时间。我想最好的方法是将数据转储到具有以下结构的临时表中:

@tempJump ([RunID], [TimeUp], [TimeDown])
然后,我将拥有计算和填充必要字段所需的所有信息

到目前为止,我已经尝试了从简单的选择/连接到可怕的游标的所有方法,但是我很难将“上升”与相应的“下降”匹配起来,并将它们与正确的“运行”放在临时表中

关于实现这一目标的最佳方法有什么想法吗

编辑:

示例架构:

    CREATE TABLE Run
    ([RunID] int, [PlayerID] int, [Score] int)
;

INSERT INTO Run
    ([RunID], [PlayerID], [Score])
VALUES
    (1, 1, 1000),
    (2, 1, 1100),
    (3, 1, 800),
    (4, 2, 1500),
    (5, 1, 900)
;

CREATE TABLE Jump
    ([JumpID] int, [RunID] int, [Time] datetime, [Type] int)
;

INSERT INTO Jump
    ([JumpID], [RunID], [Time], [Type])
VALUES
    (1, 1, '2013-08-13 18:00:04', 1),
    (2, 1, '2013-08-13 18:00:10', 2),
    (3, 2, '2013-08-13 18:02:15', 1),
    (4, 2, '2013-08-13 18:02:45', 4),
    (5, 3, '2013-08-13 18:04:20', 3),
    (6, 3, '2013-08-13 18:05:01', 2),
    (7, 4, '2013-08-13 18:10:12', 3),
    (8, 4, '2013-08-13 18:11:25', 4),
    (9, 5, '2013-08-13 18:15:00', 1),
    (10, 5, '2013-08-13 18:25:20', 4)
;

CREATE TABLE JumpType
    ([TypeID] int, [Description] varchar(12))
;

INSERT INTO JumpType
    ([TypeID], [Description])
VALUES
    (1, 'UpPlatform'),
    (2, 'DownPlatform'),
    (3, 'UpBoost'),
    (4, 'DownBoost')
;
查询的预期输出将是类似于以下内容的临时表:

RunID        PlayerID          TimeUp                     TimeDown
 1              1          '2013-08-13 18:00:04'       2013-08-13 18:00:10
编辑

根据您更新的问题,这将起作用。我加入了你的跳转类型表,而不是假设id(我个人认为假设id是一个坏主意,例如假设1和3是up类型)

此外,我还使用了一个内部连接来获得相应的向下跳跃-我假设如果跳投上升,他将下降;)

原创-在您向我们展示您的模式之前

这就是我想说的

类型表通过
isupelseasumeisdown
字段指示是上升时间还是下降时间

declare @TimeType table (Id int, Name nvarchar(20), IsUpElseAssumeIsDown bit)

insert into @TimeType (Id, Name, IsUpElseAssumeIsDown) values 
(1, '1st Up Type', 1), (2, '1st Down Type', 0),
(3, '2st Up Type', 1), (4, '2st Down Type', 0)
现在,一个设置跳转到测试

declare @Jump table ([ID] int, [RunID] int, [Time] time, [Type] int)

insert into @Jump ([ID], [RunID], [Time], [Type]) values
(1, 1, '10:00:05.000', 1), (2, 1, '10:00:15.000', 2),
(3, 2, '10:00:15.000', 3), (4, 2, '10:00:25.100', 4),
(5, 3, '10:00:25.000', 1), (6, 3, '10:00:35.200', 4),
(7, 4, '10:00:35.000', 3), (8, 4, '10:00:45.300', 4),
(9, 5, '10:00:45.000', 1), -- no down time for 1st up type 
(10, 6, '10:00:55.000', 3) -- no down time for 2nd up type
最后是一个查询以获得我们的结果

-- @tempJump ([RunID], [TimeUp], [TimeDown])

;with UpJump
as
(
    select j.RunID, j.[Time]
    from @Jump j
    inner join @TimeType t on t.Id = j.[Type] 
    where t.IsUpElseAssumeIsDown = 1
)
,DownJump
as
(
    select j.RunID, j.[Time]
    from @Jump j
    inner join @TimeType t on t.Id = j.[Type] 
    where t.IsUpElseAssumeIsDown = 0
)
select 
    u.RunID, 
    TimeUp = u.[Time],
    TimeDown = d.[Time],
    TimeDifference = DATEDIFF(MILLISECOND, u.Time, d.Time) 
from UpJump u
inner join DownJump d on d.RunID = u.RunID
结果是

RunID   TimeUp              TimeDown            TimeDifference
1       10:00:05.0000000    10:00:15.0000000    10000
2       10:00:15.0000000    10:00:25.1000000    10100
3       10:00:25.0000000    10:00:35.2000000    10200
4       10:00:35.0000000    10:00:45.3000000    10300
我已经使用cte使查询更具可读性,但您可以这样编写(仅使用连接)


当询问与查询相关的问题时,尤其是当您没有提供您的查询版本时,请至少帮助那些想要帮助您的人,并提供您的表架构、示例数据和基于它的所需输出。最好花一分钟时间用示例数据创建。@彼得谢谢你的指点。我编辑了这篇文章,希望能包含你要求的信息。如果没有,请告诉我,我会重新修改。@bullrider请看一下我的答案。这太棒了。。。。但我没有意识到,RunID、PlayerID、JumpID不是int,而是guid。这还能用吗?我真的为疏忽道歉,但是在连续14个小时这样做之后,我很幸运在这一点上诚实地键入了正确的内容,lolYes,查询是一样的。但是对于guid,您需要使用
uniqueidentifier
数据类型,而不是
int
.PS,如果您能够的话,我建议修改JumpType表,以明确哪些行表示上行类型,哪些行表示下行类型,例如添加一个位列
isupelseasumeisdown
,就像我最初的答案所示的那样……好的,那么我想我一定是弄错了模式。所有的“上升”都是正确的,但“下降”都是作为同一个字段出现的。我明天睡上几个小时后会再做一些这方面的工作。
RunID   TimeUp              TimeDown            TimeDifference
1       10:00:05.0000000    10:00:15.0000000    10000
2       10:00:15.0000000    10:00:25.1000000    10100
3       10:00:25.0000000    10:00:35.2000000    10200
4       10:00:35.0000000    10:00:45.3000000    10300
select 
    uj.RunID, 
    TimeUp = uj.[Time],
    TimeDown = dj.[Time],
    TimeDifference = DATEDIFF(MILLISECOND, uj.Time, dj.Time)
from @Jump uj
inner join @TimeType ut on ut.Id = uj.[Type] 
inner join @Jump dj on dj.RunID = uj.RunID
inner join @TimeType dt on dt.Id = dj.[Type]
where ut.IsUpElseAssumeIsDown = 1 
and dt.IsUpElseAssumeIsDown = 0
SELECT r.RunID, up.Time, down.Time, DATEDIFF(millisecond, up.Time, down.Time) as miliseconds
     FROM Run r 
LEFT JOIN Jump up   ON r.RunID = up.RunID   AND (up.Type   = 1 OR up.Type = 3)
LEFT JOIN Jump down ON r.RunID = down.RunID AND (down.Type = 2 OR down.Type = 4)
WHERE up.JumpID IS NOT NULL AND down.JumpID IS NOT NULL
select
    r.RunID, r.PlayerID, ju.Time as TimeUp, jd.Time as TimeDown
from Run as R 
    left outer join Jump as ju on ju.RunID = r.RunID and ju.[Type] in (1, 3)
    left outer join Jump as jd on jd.RunID = r.RunID and jd.[Type] in (2, 4)
select J.RunID,Max(R.PlayerID) as PlayerID,min(J.Time) as TimeUP,max(J.time) as TimeDown
from Run R
inner join Jump J on R.RunID=J.RunID
inner join JumpType JT on J.Type=JT.TypeID
where JT.Description in ('UpPlatform','DownPlatform')
or JT.Description in ('UpPlatform','DownPlatform')
group by J.RunID
having COUNT(J.RunID)>1