2013-08-14 7 views
1

Так у меня есть пара таблиц структурированы похож на это:SQL Server: Сумма DateDiff из нескольких рядов

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

  • Jump ([ID], [RunID], [Time], [Type])

Есть 4 "типа" времени 2 "вверх" и 2 "вниз".

Мне нужно получить время между «вверх» и «вниз» на данном прогоне.

В принципе, во время «запуска», когда происходит «прыжок», я записываю время нарастания, а вниз записывается на соответствующей посадке (только одна пара за ход). В конце «пробега» мне нужно отобразить общее время «в воздухе», а также время за прыжок. Я думал, что лучший способ сделать это будет сбрасывать в временную таблицу со следующей структурой:

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

Тогда я бы иметь всю необходимую информацию для расчета и заполнения необходимых полей.

До сих пор я пробовал все: от простых подбора/присоединения к страшным курсорам, но у меня возникают проблемы с совпадением «ups» с соответствующими «downs» и помещением их в таблицу temp с правильным «прогоном».

Любые идеи о наилучшем способе достижения этого?

EDIT:

Пример схема:

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 
+2

Задавая вопросы, связанные с запросом, особенно, если вы не предоставите свою версию запроса, пожалуйста, по крайней мере, помочь тем, кто хочет, чтобы помочь вам и обеспечить ваш стол (ы) схему, выборочные данные и желаемый результат на основе этого. Лучше всего потратьте одну минуту и ​​создайте [sqlfiddle] (http://sqlfiddle.com) с вашими примерными данными. – peterm

+0

@peterm Спасибо за указатели. Я редактировал сообщение, надеюсь, включая запрошенную вами информацию. Если нет, дайте мне знать, и я снова пересмотрю его. – mwhobrey

ответ

2

EDIT

Исходя из вашего обновленного вопроса, это сработает.Я присоединился на вашем типа скачка таблицы, а не предполагая, что идентификаторы (лично я думаю, что его плохая идея взять на себя идентификаторы, например, предположим, 1 и 3 являются до типа)

Также я использовал внутренний присоединиться, чтобы получить соответствующий вниз прыжок - Я предполагаю, что если перемычка идет вверх, он сойдет;)

select 
    r.RunID, 
    r.PlayerID, 
    TimeUp = uj.[Time], 
    TimeDown = dj.[Time], 
    TimeDifference = DATEDIFF(MILLISECOND, uj.Time, dj.Time) 
from @Run r 
inner join @Jump uj on uj.RunID = r.RunID 
inner join @JumpType ut on ut.TypeID = uj.[Type] 
inner join @Jump dj on dj.RunID = uj.RunID 
inner join @JumpType dt on dt.TypeID = dj.[Type] 
where ut.[Description] like '%Up%' 
and dt.[Description] like '%Down%' 

ORIGINAL - перед тем, как показал нам свою схему

Вот что я кулачок с

Тип таблицы указывают, если его вверх или вниз время с IsUpElseAssumeIsDown поле

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 

Я использовал КТР, чтобы сделать запрос более удобным для чтения, но вы могли бы написать, как это (только с присоединяется)

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 
+0

Это замечательно .... Но я не понял, что RunID, PlayerID, JumpID не являются Ints, они являются GUID. Будет ли это работать? Я действительно извиняюсь за недосмотр, но после этого в течение 14 часов подряд мне повезло, что я правильно набрал на этом месте lol – mwhobrey

+0

Да, вопрос такой же. Но для подсказок вам нужно использовать тип данных 'uniqueidentifier' вместо' int'. –

+0

PS, если вы можете предложить изменить таблицу JumpType, чтобы сделать ее явной, какие строки представляют типы и которые являются нисходящими типами, например, добавить бит столбца «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 

sqlFiddle

1
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) 

sql fiddle demo

0
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 

SQL Fiddle

+0

@bullrider Пожалуйста, посмотрите на мой ответ. – Luv

Смежные вопросы