获取每秒所有已开始但尚未完成的行的运行计数和值的总和

Posted

技术标签:

【中文标题】获取每秒所有已开始但尚未完成的行的运行计数和值的总和【英文标题】:Get running count and sums of value of all rows that are started but not yet finished for each second 【发布时间】:2021-01-12 15:00:05 【问题描述】:

我有一些看起来像这样的事件数据:

| time                    | id | status   | value |
|-------------------------|----|----------|-------|
| 2020-08-26T21:29:01.000 | 2  | started  | 8     |
| 2020-08-26T21:29:01.000 | 3  | started  | 4     |
| 2020-08-26T21:29:02.000 | 2  | finished | 8     |
| 2020-08-26T21:29:03.000 | 4  | started  | 12    |
| 2020-08-26T21:29:04.000 | 5  | started  | 2     |
| 2020-08-26T21:29:05.000 | 6  | started  | 24    |
| 2020-08-26T21:29:06.000 | 4  | finished | 12    |
| 2020-08-26T21:29:06.000 | 3  | finished | 4     |
| 2020-08-26T21:29:07.000 | 1  | finished | 1     |
| 2020-08-26T21:29:10.000 | 7  | started  | 4     |

请注意,事件数据是在事情开始后开始记录的,并且有些事件尚未完成。

然后我试图获取行的运行计数和每秒值的运行总和。

一想到运行计数,我就会想到窗口查询,但我正在努力弄清楚如何从这些数据中得到我期望的输出。

理想情况下,我希望得到以下结果:

| time                    | count | sum_values |
|-------------------------|-------|------------|
| 2020-08-26T21:29:00.000 | 1     | 1          |
| 2020-08-26T21:29:01.000 | 3     | 13         |
| 2020-08-26T21:29:02.000 | 2     | 5          |
| 2020-08-26T21:29:03.000 | 3     | 17         |
| 2020-08-26T21:29:04.000 | 4     | 19         |
| 2020-08-26T21:29:05.000 | 5     | 43         |
| 2020-08-26T21:29:06.000 | 3     | 29         |
| 2020-08-26T21:29:07.000 | 2     | 28         |
| 2020-08-26T21:29:08.000 | 2     | 28         |
| 2020-08-26T21:29:09.000 | 2     | 28         |
| 2020-08-26T21:29:10.000 | 3     | 32         |
| 2020-08-26T21:29:11.000 | 3     | 32         |

如果答案没有考虑到在事件开始记录之前正在运行的 1 id 记录,我也会很高兴,这将产生以下结果:

| time                    | count | sum_values |
|-------------------------|-------|------------|
| 2020-08-26T21:29:00.000 | 0     | 0          |
| 2020-08-26T21:29:01.000 | 2     | 12         |
| 2020-08-26T21:29:02.000 | 1     | 4          |
| 2020-08-26T21:29:03.000 | 2     | 16         |
| 2020-08-26T21:29:04.000 | 3     | 18         |
| 2020-08-26T21:29:05.000 | 4     | 42         |
| 2020-08-26T21:29:06.000 | 2     | 28         |
| 2020-08-26T21:29:07.000 | 2     | 28         |
| 2020-08-26T21:29:08.000 | 2     | 28         |
| 2020-08-26T21:29:09.000 | 2     | 28         |
| 2020-08-26T21:29:10.000 | 3     | 32         |
| 2020-08-26T21:29:11.000 | 3     | 32         |

由于 Athena/Presto 不支持完全连接,我能够通过以下查询(也在 SQL Fiddle)获得每个 id 的开始和停止时间:

WITH started AS (
  SELECT *
  FROM foo
  WHERE status = 'started'
), finished AS (
  SELECT *
  FROM foo
  WHERE status = 'finished'
)
SELECT started.time AS started_time, finished.time AS finished_time, started.id, started.value
FROM started LEFT JOIN finished ON started.id = finished.id

【问题讨论】:

您想要在结果集中的时间数据中是否有任何间隔(秒)?如果是这样,您还需要加入“理货”表” 是的,会有差距。我也可以编辑问题以使其更清楚。 时间戳也是毫秒级的,但我还是要date_trunc他们,所以你可以认为它只是秒级。 【参考方案1】:

我想你想要一个累积条件和:

select time,
       sum(sum(case when status = 'started' then 1
                    when status = 'finished' then -1
               end)
          ) over (order by time) as running_count,
       sum(sum(case when status = 'started' then value
                    when status = 'finished' then - value
                end)
          ) over (order by time) as running_value
from foo
group by time

sum()s 需要嵌套,因为一个用于窗口函数,另一个用于聚合。

【讨论】:

乍一看,这似乎应该运行给我,但是当我在 Athena 中运行此查询时,我收到以下错误:Error running query: SYNTAX_ERROR: line 2:8: '"sum"((CASE WHEN ("status" = 'started') THEN 1 WHEN ("status" = 'finished') THEN -1 END)) OVER (ORDER BY "time" ASC)' must be an aggregate expression or appear in GROUP BY clause @ydaetskcoR 。 . .固定的。 sum()s 需要嵌套,一个用于聚合,一个用于窗口函数。

以上是关于获取每秒所有已开始但尚未完成的行的运行计数和值的总和的主要内容,如果未能解决你的问题,请参考以下文章

如何获得动态创建的行的总价格?

Django 计数具有重复值的行

Laravel - 获取今天在开始和结束之间的行

使用Python DictReader获取特定的行和值

如何获取 SQL 中具有 MAX 和 MIN 值的行的 ID

比较多行的行值 (R)