基于分析条件的基于行的时间差

Row based time difference based on condition for Analytics

我在名为 TABLE 的 table 中有以下数据:

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

    /------------------------------------------------------------------------\
    |      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   |
    \------------------------------------------------------------------------/

我已将此查询编写为根据 EVENTTYPESTARTEND 值获取时差:

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 - 如果在 START 和 [= 之间有任何其他事件14=] 那么我们需要跳过那个特定的 CharacterID.

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

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

我们如何实现这一目标?

其次,在POWERBI中有什么简单的方法可以实现并显示计数和时差吗?

基于一些假设:

  • 对于两个相关的 EVENTTYPE 值("START" 和 "END")
  • ,每个 CharacterId 您只能有一个记录
  • 具有 EVENTTYPE 值 "END" 的任何记录在 TRIGGERTIME 中的日期时间值始终比具有 [=12] 的相同 CharacterId 的记录晚=] "START".

您可以使用类似的东西:

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

无论 CharacterID 启动会话多少次,这都会找到每个 START 记录,然后找到以下 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