Sql 使用开始和停止时间对时间序列事务进行分组和汇总
我有一系列的交易。我需要总结处理这些事务所花费的总时间,以及从一个组移动到另一个组时中断的组内事务的计数。这意味着,如果该组在多个时隙中有一组事务,则该组可以重复。我正在使用oracle数据库和SQL来做这个总结。我正在寻找一些帮助来编写SQL来总结这些数据。我用各种分析和分组函数尝试了许多不同的查询 来源数据:Sql 使用开始和停止时间对时间序列事务进行分组和汇总,sql,oracle,group-by,window-functions,analytic-functions,Sql,Oracle,Group By,Window Functions,Analytic Functions,我有一系列的交易。我需要总结处理这些事务所花费的总时间,以及从一个组移动到另一个组时中断的组内事务的计数。这意味着,如果该组在多个时隙中有一组事务,则该组可以重复。我正在使用oracle数据库和SQL来做这个总结。我正在寻找一些帮助来编写SQL来总结这些数据。我用各种分析和分组函数尝试了许多不同的查询 来源数据: User ID | Area | Start Time | End Time | Transaction ID jsmith 24 07-JUL-14 09.06.21.00000
User ID | Area | Start Time | End Time | Transaction ID
jsmith 24 07-JUL-14 09.06.21.000000000 AM 07-JUL-14 09.14.51.000000000 AM 63665020
jsmith 24 07-JUL-14 11.06.01.000000000 AM 07-JUL-14 11.07.10.000000000 AM 63679145
jsmith 24 07-JUL-14 11.16.36.000000000 AM 07-JUL-14 11.16.51.000000000 AM 63680441
jsmith 21 07-JUL-14 11.33.05.000000000 AM 07-JUL-14 11.33.18.000000000 AM 63683133
jsmith 21 07-JUL-14 11.48.55.000000000 AM 07-JUL-14 11.51.03.000000000 AM 63685906
jsmith 21 07-JUL-14 11.55.48.000000000 AM 07-JUL-14 11.56.01.000000000 AM 63686651
jsmith 24 07-JUL-14 12.32.51.000000000 PM 07-JUL-14 12.32.55.000000000 PM 63690943
jsmith 24 07-JUL-14 12.32.55.000000000 PM 07-JUL-14 12.33.02.000000000 PM 63690956
jsmith 21 07-JUL-14 12.42.05.000000000 PM 07-JUL-14 12.42.11.000000000 PM 63692212
jsmith 21 07-JUL-14 12.44.38.000000000 PM 07-JUL-14 12.44.43.000000000 PM 63692600
jsmith 25 07-JUL-14 01.01.18.000000000 PM 07-JUL-14 01.01.52.000000000 PM 63694808
jsmith 25 07-JUL-14 01.03.43.000000000 PM 07-JUL-14 01.04.44.000000000 PM 63695353
jsmith 25 07-JUL-14 01.12.30.000000000 PM 07-JUL-14 01.14.06.000000000 PM 63697002
jsmith 24 07-JUL-14 01.14.11.000000000 PM 07-JUL-14 01.14.23.000000000 PM 63697045
jsmith 24 07-JUL-14 01.21.41.000000000 PM 07-JUL-14 01.23.46.000000000 PM 63699080
所需汇总数据:(实体模型)
要解决这些问题,需要为每个连续行生成一些组号。在这里,我首先使用
LAG
在每次启动新组时生成一个记号。使用SUM
的外部查询将计算从第一个到当前的勾号,以生成组号:
SELECT "Area",
MIN("Start Time") as "Start Time",
MAX("End Time") as "End Time",
SUM("End Time" - "Start Time")*24*60 as "Total Minutes",
COUNT("Transaction ID") as "#Transaction ID"
FROM (
SELECT SUM(clk)
OVER (ORDER BY "Start Time"
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) grp,
-- ^^^^^^^^^^^^^
-- Generate a group number by summing the tick marks
V1.*
FROM (
SELECT CASE
WHEN LAG("Area", 1, NULL) OVER (ORDER BY "Start Time") = "Area"
THEN 0
ELSE 1
END clk,
-- ^^^^^^^^
-- Set a tick mark ("clock") to 1 each time we change group
T.*
FROM T
) V1
) V2
GROUP BY GRP, "Area"
ORDER BY "Start Time"
看
有点难理解,但这也适用:
SELECT "Area",
MIN("Start Time") as "Start Time",
MAX("End Time") as "End Time",
SUM("End Time" - "Start Time")*60 as "Total Minutes",
COUNT("Transaction ID") as "#Transaction ID"
FROM (
SELECT ROWNUM-ROW_NUMBER()
OVER (PARTITION BY "Area" ORDER BY "Start Time") grp,
T.*
FROM T
ORDER BY "Start Time"
) V
GROUP BY GRP, "Area"
ORDER BY "Start Time"
看
在这种情况下,请注意,您可以使用重复的
grp
——但只能用于不同的组。除非行是连续的。关于这一点的讨论,请参阅下面的评论。这里不需要分析,只需要聚合。我不明白为什么在所需的输出中有几行面积=24。您的“事务”是如何进行分组的?当遇到不同的区域时,它表示一个新的分组集,因此前3个24的组合在一起,接下来3个21的组合,接下来2个24的组合,接下来2个21的组合,接下来3个25的组合。。。等等。现在我认为分析超前和滞后可能是有用的,并将其包装在一个CTE中,然后进行分组……我对你如何提出这个概念感到敬畏;但我正在努力,如果这会遇到重复的grp号码。谢谢!这个概念真的很有帮助,看起来我能得到我需要的东西。当用户在不同的组中工作时,我们需要重复的组号来跟踪全天的指标。示例:早上A组到B组再到A组再到C组@xQbert完全正确!我不知道我怎么能不去想那件事。当然,您可以创建具有重复grp编号的数据。我把我的答案换成了一个更简单的解决方案——那一次,你肯定没有重复的…@xQbert事实上,它工作得很好,就像你可以有重复的grp一样——但不适用于相同的“区域”
,除非行是连续的。GRP的组“区域”
考虑到了这一点。
SELECT "Area",
MIN("Start Time") as "Start Time",
MAX("End Time") as "End Time",
SUM("End Time" - "Start Time")*60 as "Total Minutes",
COUNT("Transaction ID") as "#Transaction ID"
FROM (
SELECT ROWNUM-ROW_NUMBER()
OVER (PARTITION BY "Area" ORDER BY "Start Time") grp,
T.*
FROM T
ORDER BY "Start Time"
) V
GROUP BY GRP, "Area"
ORDER BY "Start Time"