【发布时间】:2016-02-04 22:19:59
【问题描述】:
我需要写一个postgressql函数来处理一些时间序列数据,我想循环遍历每个时间步,并决定是否需要更新未来几个时间步中的值,它将是更新的当循环迭代到以下时间步时应用决策的值。我希望我已经解释清楚了。
因此以表格为例:
CREATE TEMPORARY TABLE datatable (
unixdatetime integer,
value integer,
);
INSERT INTO datatable (unixdatetime, value) VALUES
(1,56),
(2,23),
(3,7),
(4,68),
(5,31),
(6,42);
我已尝试对其应用以下 for 循环:
FOR r IN
SELECT * FROM datatable
LOOP
DROP TABLE IF EXISTS currentdata;
CREATE TEMPORARY TABLE currentdata AS (
SELECT dt.unixdatetime as currentTime,
lead(dt.unixdatetime,1) OVER (ORDER BY dt.unixdatetime) AS lead1stTime,
dt.value AS currentValue,
lead(dt.value,1) OVER (ORDER BY dt.unixdatetime) AS lead1stVal
FROM datatable dt
);
_counter = 0;
IF (SELECT currentValue%2 FROM currentdata) = 1
THEN _counter = _counter + 1;
END IF;
IF (SELECT lead1stVal%2 FROM currentdata) = 1
THEN _counter = _counter + 1;
END IF;
UPDATE datatable dt
SET value = (CASE WHEN _counter = 2 AND cd.currentValue <> 888 THEN 999
ELSE cd.currentValue
END)
FROM currentdata cd
WHERE dt.unixdatetime = cd.currentTime;
UPDATE datatable dt
SET value = (CASE WHEN _counter = 2 THEN 888
ELSE cd.lead1stVal
END)
FROM currentdata cd
WHERE dt.unixdatetime = cd.lead1stTime;
END LOOP;
而我的预期结果是:
| unixdatetime | Value |
| 1 | 56 |
| 2 | 999 |
| 3 | 888 |
| 4 | 68 |
| 5 | 31 |
| 6 | 42 |
正如大家所见,我仍然无法切换到 postgresql 思维模式,并且仍在尝试使用 python 和 C++ 等语言中的技巧,这些技巧在 postgressql 中不起作用。我注意到的是:
循环中的每个语句都在整个表上执行,然后再转到循环中的下一条语句。而是在迭代到表的行之前顺序执行所有语句。
因为 1.,_counter 不能提供与其他语言的 for 循环相同的效果。我确实需要在 for 循环中使用计数器,因为实际任务需要我提前查看超过 2 个时间步长的值。
感谢任何有用的解决方法建议。
提前致谢,
杰森
【问题讨论】:
-
create table是错误的。那应该是CREATE TEMPORARY TABLE currentdata as select ...选择周围没有括号,并且as丢失了。 -
这样的预期结果是什么?代码充满了错误,对我来说没有任何意义。
datatable更新后的内容应该如何? -
感谢您的评论,我已经编辑了原帖。我在引用我的原始代码时直接在文本窗口中输入了这个简化版本,因此请原谅错误。
-
我不明白更新这两个值的逻辑。为什么第二行的值更新为 999,第三行的值更新为 888?您为什么不解释您要解决的实际问题,而不仅仅是转储代码。顺便说一句:如果从
select返回多于一行,IF (SELECT lead1stVal%2 FROM currentdata) = 1应该会失败。为什么不使用循环中的记录呢? -
我已经将我原来代码的逻辑简化为:如果连续两行都是奇数,则将第一行更新为999,将第二行更新为888。我的印象是里面的所有内容该循环仅在当前迭代上运行,并且我找不到专门在循环内的当前迭代上调用的 postgresql 示例。希望这能澄清逻辑。我的主要障碍仍然是在迭代到下一行之前将 for 循环中的多个语句应用于单行。
标签: postgresql loops for-loop counter