视图中的数据如下所示:
id time revs m_id tag_id
320518 2017-04-05 14:01:25 216210396 1 1
320620 2017-04-05 14:11:33 216217766 1 1
27346 2017-12-09 15:15:52 699 2 1
27347 2017-12-09 15:19:52 1618 2 1
目标:我需要通过执行以下操作来计算每分钟的转速:
(row2 rev- row1 rev)/ (row2 time - row1 time)=revs per minute
对于每两行。也适用于每个m_id(1和2)。换句话说,当m_id改变时 - 它将执行与该m_id相关联的行。它还需要按tag_id分组。
我需要结果数据如下所示:
time m_id tag_id time_diff rev_diff rpm
2017-04-05 14:11:33 1 1 10.13 7370 727.54
2017-12-09 15:15:52 2 1 4 919 229.75
有数千行。我已经将视图设置为m_id然后按时间排序的位置。
将它全部保存在同一个表/视图中的原因是因为我可以有任意数量的m_ids。我需要它是动态的,所以无论创建多少个m_id,我仍然可以确定rpms。
我原来的解决方案是为每个m_id创建过滤后的视图,但这不适用于“插入式”程序。
更新:4/20/17
我使用@Tim Biegeleisen答案作为模板(使用我的实际字段名称)调整了我的脚本。
WITH cte AS (
SELECT
machine_id_id,
rfid_tag_id,
"event_at",
LAG("event_at") OVER (ORDER BY "event_at" PARTITION BY machine_id_id) AS prev_time,
rev_count, LAG(rev_count) OVER (ORDER BY "event_at" PARTITION BY machine_id_id) AS prev_revs
FROM machines_status_updates
)
SELECT t.*,
(rev_count - tprev_revs) /
(EXTRACT(EPOCH FROM (t.event_at - t.prev_time)) / 60) AS rpm
FROM cte t
WHERE t.prev_time IS NOT NULL
它仍在抛出语法错误 - 在第一个PARTITION BY - 但我没有看到语法错误。
错误:
sql> WITH cte AS (
SELECT
machine_id_id,
rfid_tag_id,
"event_at",
LAG("event_at") OVER (ORDER BY "event_at" PARTITION BY machine_id_id) AS prev_time,
rev_count,
LAG(rev_count) OVER (ORDER BY "event_at" PARTITION BY machine_id_id) AS prev_revs
FROM machines_status_updates
)
[2017-04-20 10:36:16] [42601] ERROR: syntax error at or near "PARTITION"
[2017-04-20 10:36:16] Position: 154
通过文档(因为这个CTE对我来说有点新鲜) - 一切看起来都对 - 我找不到我错过的东西。
编辑(2017年4月5日更新) - 取得进展
这是脚本的最新版本(消除PARTITION Error然后除以零错误)
WITH cte AS (
SELECT
machine_id_id,
rfid_tag_id,
event_at,
LAG(event_at) OVER (ORDER BY machine_id_id, event_at) AS prev_time,
rev_count,
LAG(rev_count) OVER (ORDER BY machine_id_id, event_at) AS prev_revs
FROM machines_status_updates
)
SELECT t.*,
(t.rev_count - t.prev_revs) / NULLIF(
(EXTRACT(EPOCH FROM (t.event_at - t.event_at)) / 60), 0) AS rpm
FROM cte t
WHERE t.prev_time IS NOT NULL;
RPM在整个数据集中返回NULL - 行似乎都运行良好。有什么想法吗?
最终答案: WOOOHOOOO!终于明白了! :D来自@Tim Biegeleisen的回答。
最终剧本:
WITH cte AS (
SELECT
machine_id_id,
rfid_tag_id,
event_at,
LAG(event_at) OVER (ORDER BY machine_id_id, event_at) AS prev_time,
rev_count,
LAG(rev_count) OVER (ORDER BY machine_id_id, event_at) AS prev_revs
FROM machines_status_updates
)
SELECT t.*, (t.rev_count - t.prev_revs)AS rev_diff, (EXTRACT(EPOCH FROM (t.event_at - t.prev_time)
) / 60) AS time_diff,
(t.rev_count - t.prev_revs) / NULLIF(
(EXTRACT(EPOCH FROM (t.event_at - t.prev_time)) / 60), 0) AS rpm
FROM cte t
WHERE t.prev_time IS NOT NULL;
它是null因为我从它自己减去t.event而不是prev_time。我添加了一些列,以便我可以验证rpms。
最终结果:
答案 0 :(得分:2)
WITH cte AS (
SELECT
m_id,
tag_id,
"time",
LAG("time") OVER (ORDER BY "time" PARTITION BY m_id) AS prev_time,
revs,
LAG(revs) OVER (ORDER BY "time" PARTITION BY m_id) AS prev_revs
FROM yourTable
)
SELECT t.*,
(t.revs - t.prev_revs) /
(EXTRACT(EPOCH FROM (t.time - t.prev_time)) / 60) AS rpm
FROM cte t
WHERE t.prev_time IS NOT NULL