2017-01-11 7 views
0

я следующие данные в таблице под названием TABLE:

EDIT: Добавлен еще пару строк с Characterid: 26052013030101, который пропустили.Row на основе условия для Analytics

 
    /------------------------------------------------------------------------\ 
    |  CharacterID  |  EVENTTYPE  |  TRIGGERTIME   | 
    |----------------------+-------------------+-----------------------------| 
    | 11052016190101 | START   | 2017-06-01 13:35:38.000 | 
    | 11052016190101 | END   | 2017-01-06 08:05:18.620 | 
    | 01012016170101 | START   | 2017-06-01 13:33:18.000 | 
    | 01012016170101 | Player Left | 2017-06-01 13:35:21.000 | 
    | 01012016170101 | END   | 2017-06-01 13:38:22.000 | 
    | 26052013030101 | START   | 2017-06-01 13:35:39.000 | 
    | 26052013030101 | RESET   | 2017-06-01 13:35:50.000 | 
    \------------------------------------------------------------------------/ 

Я написал этот запрос, чтобы получить разницу во времени, основанный на START и END значений EVENTTYPE:

SELECT 
    cp_start.characterid, 
    MAX(cp_start.triggertime) AS start_time, 
    cp_end.triggertime AS end_time, 
    datediff(second, MAX(cp_start.triggertime), cp_end.triggertime) 
FROM 
    TABLE AS cp_start 
INNER JOIN 
    TABLE AS cp_end ON (
     cp_start.CharacterID= cp_end.CharacterID 
    AND 
     cp_end.triggertime > cp_start.triggertime) 
WHERE cp_start.eventtype = 'START' 
AND cp_end.eventtype = 'END' 
GROUP BY cp_start.characterid, cp_Start.TriggerTime, cp_end.TriggerTime 

Однако то, что мы хотим, чтобы получить разницу во времени для указанных выше условиях - т.е. START и END - и если есть какое-либо другое событие между START и END, тогда нам необходимо пропустить этот код CharacterID.

В приведенном выше примере видим CharacterID = 01012016170101, есть строка с EVENTTYPE='Player Left' строки между рядами с START и END значений для EVENTTYPE, которые должны быть пропущены или не следует рассматривать как.

EDIT: В приведенном выше значении = 26052013030101 имеется только СТАРТ, но нет КОНЕЦ. У этого есть СБРОС, то есть мы не должны рассматривать это значение, показывая результат. END OF EDIT

Как это достичь?

Во-вторых, есть ли простой способ достичь этого в POWERBI и отображать разницу во времени и времени?

+0

Могут ли такие же «CharacterId» «START» и «END» несколько раз? Или будет ли когда-либо только одна запись на 'CharacterId' с каждым значением' EVENTTYPE' из «START» и «END»? – 3N1GM4

+0

Кроме того, есть ли опечатка в ваших примерах данных или должно быть 3 разных значения CharacterId? Похоже, возможно, тот, который показан как '01012013010101', должен быть' 01012016170101', как две строки под ним? – 3N1GM4

+0

И правильно ли, что дата «END» для 'CharacterId = 11052016190101' является более ранней датой, чем дата« START »для этого же« CharacterId »? Или эти значения DateTime в формате yyyy-dd-mm или что-то еще? – 3N1GM4

ответ

1

Найдет каждый START запись независимо от того, сколько раз CharacterID начинает сеанс, а затем находит следующую END запись:

declare @t table(CharacterID bigint,EVENTTYPE nvarchar(100),TRIGGERTIME datetime); 
insert into @t values 
(11052016190101,'START','2017-01-01 13:35:38.000') 
,(11052016190101,'END','2017-01-06 08:05:18.620') 
,(01012013010101,'START','2017-06-01 13:33:18.000') 
,(01012013010101,'Player Left','2017-06-01 13:35:21.000') 
,(01012013010101,'END','2017-06-01 13:38:22.000') 
,(01012013010101,'START','2017-07-01 13:33:18.000') 
,(01012013010101,'Player Left','2017-07-01 13:35:21.000') 
,(01012013010101,'END','2017-07-01 13:38:22.000'); 

with Starts as 
(
    select CharacterID 
      ,EVENTTYPE 
      ,TRIGGERTIME 
    from @t 
    where EVENTTYPE = 'START' 
) 
select s.CharacterID 
     ,s.TRIGGERTIME as StartTime 
     ,e.TRIGGERTIME as EndTime 
from Starts s 
    outer apply (select top 1 TRIGGERTIME 
        from @t 
        where CharacterID = s.CharacterID 
         and TRIGGERTIME > s.TRIGGERTIME 
         and EVENTTYPE = 'END' 
        order by TRIGGERTIME 
       ) e 
order by CharacterID 
     ,StartTime; 

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

CharacterID | StartTime    | EndTime 
---------------+-------------------------+------------------------ 
1012013010101 | 2017-06-01 13:33:18.000 | 2017-06-01 13:38:22.000 
1012013010101 | 2017-07-01 13:33:18.000 | 2017-07-01 13:38:22.000 
11052016190101 | 2017-01-01 13:35:38.000 | 2017-01-06 08:05:18.620 
+0

решение выглядит хорошо, но по какой-то причине, если есть «СТАРТ», но нет «КОНЕЦ» для того же символа, тогда приведенный выше запрос не обеспечивает наилучшего результата. – aioracle

+0

Если у самого последнего 'START' нет' END', вы получаете значение 'null'' EndTime', которое вы можете заменить любым значением, которое вам нравится, с помощью функции isnull или исключить в '' '' '' '' '. Если у вас есть несколько записей «START» без записи «END» для того же «CharacterID», наверняка у вас есть проблемы с данными, которые необходимо решить, прежде чем делать этот анализ? – iamdave

+0

это работает. Спасибо. – aioracle

1

Основываясь на некоторых предположениях:

  • Вы только когда-либо одна запись на CharacterId для каждого из двух соответствующих EVENTTYPE значений («START» и «END»)
  • Любая запись с EVENTTYPE значением «END» всегда будет иметь более позднее значение даты и времени в TRIGGERTIME, чем запись для того же CharacterId с EVENTTYPE «СТАРТ».

Вы могли бы использовать что-то вроде:

SELECT DISTINCT 
    c.CharacterId, 
    start.TRIGGERTIME AS StartTime, 
    [end].TRIGGERTIME AS EndTime, 
    DATEDIFF(s, start.TRIGGERTIME, [end].TRIGGERTIME) AS [TimeDiff(seconds)] 
FROM [TABLE] c 
OUTER APPLY 
(
    SELECT TRIGGERTIME 
    FROM [TABLE] s 
    WHERE s.CharacterId = c.CharacterId 
    AND s.EVENTTYPE = 'START' 
) start 
OUTER APPLY 
(
    SELECT TRIGGERTIME 
    FROM [TABLE] e 
    WHERE e.CharacterId = c.CharacterId 
    AND e.EVENTTYPE = 'END' 
) [end] 

Если вы хотите, чтобы представить разницу во времени по-другому, чем просто количество секунд, которые могут быть обработаны отдельно и есть много других вопросов, на SO, которые справляются с этим.

Вы можете в равной степени переместить OUTER APPLY s в подзапросы в предложении SELECT, но таким образом сделать логику немного легче следовать ИМХО.