0

我在一个名为的表中有以下数据TABLE

编辑:添加了另外几行Characterid: 26052013030101,但被遗漏了。

    /---------------------------------------------------- ----------------------\
    | 字符ID | 事件类型 | 触发时间 |
    |----------------------+--------------------+------ ----------------------|
    | 11052016190101 | 开始 | 2017-06-01 13:35:38.000 |
    | 11052016190101 | 结束 | 2017-01-06 08:05:18.620 |
    | 01012016170101 | 开始 | 2017-06-01 13:33:18.000 |
    | 01012016170101 | 球员左 | 2017-06-01 13:35:21.000 |
    | 01012016170101 | 结束 | 2017-06-01 13:38:22.000 |
    | 26052013030101 | 开始 | 2017-06-01 13:35:39.000 |
    | 26052013030101 | 重置 | 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

但是,我们想要的是获得上述条件的时间差 - 即STARTEND- 如果在 和 之间有任何其他事件STARTEND那么我们需要跳过那个特定CharacterID的 。

在上面的示例中,请参见CharacterID = 01012016170101,在需要跳过或不考虑EVENTTYPE='Player Left'的行之间有一行行STARTEND值。EVENTTYPE

编辑:在上面,characterid = 26052013030101,只有开始但没有结束。它有 RESET,这意味着我们在显示结果时不应该考虑这个值。编辑结束

我们如何实现这一目标?

其次,在POWERBI中是否有任何简单的方法可以实现这一点并显示计数和时间差?

4

2 回答 2

1

基于一些假设:

  • CharacterId对于两个相关EVENTTYPE值(“START”和“END”)中的每一个,您只有一个记录
  • 任何EVENTTYPE值为“END”的记录将始终具有比“START”相同的记录更晚的日期时间值TRIGGERTIMECharacterIdEVENTTYPE

你可以使用类似的东西:

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 APPLYs 移动到子句中的子查询中SELECT,但是这种方式使逻辑更容易遵循恕我直言。

于 2017-01-11T11:24:37.580 回答
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
于 2017-01-11T13:38:20.993 回答