基于分析条件的基于行的时间差
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 |
\------------------------------------------------------------------------/
我已将此查询编写为根据 EVENTTYPE
的 START
和 END
值获取时差:
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
和 [= 之间有任何其他事件14=] 那么我们需要跳过那个特定的 CharacterID
.
在上面的示例中,参见 CharacterID = 01012016170101
,在具有 EVENTTYPE
的 START
和 END
值的行之间有一行 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
我在名为 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 | \------------------------------------------------------------------------/
我已将此查询编写为根据 EVENTTYPE
的 START
和 END
值获取时差:
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
和 [= 之间有任何其他事件14=] 那么我们需要跳过那个特定的 CharacterID
.
在上面的示例中,参见 CharacterID = 01012016170101
,在具有 EVENTTYPE
的 START
和 END
值的行之间有一行 EVENTTYPE='Player Left'
行需跳过或不考虑.
编辑:在上面,characterid = 26052013030101,只有START没有END。它有 RESET,这意味着我们在显示结果时不应该考虑这个值。 编辑结束
我们如何实现这一目标?
其次,在POWERBI中有什么简单的方法可以实现并显示计数和时差吗?
基于一些假设:
- 对于两个相关的
EVENTTYPE
值("START" 和 "END") ,每个 - 具有
EVENTTYPE
值 "END" 的任何记录在TRIGGERTIME
中的日期时间值始终比具有 [=12] 的相同CharacterId
的记录晚=] "START".
CharacterId
您只能有一个记录
您可以使用类似的东西:
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