如何解决寻找类似滞后函数但更复杂的东西SQL
我为如何做到这一点而绞尽脑汁,我不认为这是可能的,但不确定该寻找什么。因此,以下是数据的子集(使用示例编号)
我想像一个滞后函数一样将值拉低,然后乘以%列,得到如下所示的内容(每次使用新的计算值)
我感觉不可能,但是手指交叉了。如果有帮助,请使用Redshift
预先感谢
解决方法
Amazon Redshift基于Postgresql,即使存在一些差异(例如https://docs.aws.amazon.com/redshift/latest/dg/c_redshift-and-postgres-sql.html),它也确实包含了lag()
函数(请参见https://docs.aws.amazon.com/redshift/latest/dg/r_WF_LAG.html)。
所以您的陈述可能看起来像这样(在postgres中有效)
UPDATE yourtable
SET number = (q1.percentage * q1.prevnumber)
FROM (SELECT Months,percentage,lag(number) OVER (ORDER BY Months) as prevnumber
FROM yourtable) q1
WHERE yourtable.Months = q1.Months AND yourtable.Months > 0;
您还可以通过在最后一个AND Number IS NULL
子句中添加类似WHERE
之类的条件来仅更新那些尚无值的字段。而且,如果您有多年的经验,那么当然需要在订购时考虑到这一点。
有关这两个SO帖子的更多详细讨论和示例,请参见:
Is there a way to access the "previous row" value in a SELECT statement?
PostgreSQL update query with "lag()" window function
编辑:此查询不会单次更新所有行,因为该查询基于原始表条目,并且在更新时,第10个月的行将具有NULL值作为乘法的因子之一(数字从第9个月开始。
您可以使用多种方法来获得所需的结果。我在下面添加了两个示例。两者都可以在postgres中工作,也应该在redshift中工作:
(1)您可以使用UPDATE
循环将上述WHILE
语句重复适当的次数。以下函数迭代更新表,直到number
为NULL
的行不再存在为止:
CREATE OR REPLACE FUNCTION update_numbers() RETURNS void AS
$BODY$
BEGIN
WHILE (SELECT COUNT(*) FROM yourtable WHERE number IS NULL) > 0 LOOP
UPDATE yourtable
SET number = (q1.percentage * q1.prevnumber)
FROM (SELECT Months,lag(number) OVER (ORDER BY Months) as prevnumber
FROM yourtable) q1
WHERE yourtable.number IS NULL
AND yourtable.Months = q1.Months
AND yourtable.Months > 0;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
(2)您可以使用CURSOR
遍历number
为NULL
的各个行,并一次更新每个行:
CREATE OR REPLACE FUNCTION update_numbers() RETURNS void AS
$BODY$
DECLARE
rec record;
prev numeric;
cur cursor for (SELECT * FROM yourtable WHERE number IS NULL ORDER BY Months) FOR UPDATE;
BEGIN
FOR rec in cur LOOP
SELECT prevnumber INTO prev FROM (SELECT Months,lag(number) OVER (ORDER BY Months) as prevnumber
FROM yourtable) q1 where q1.months = rec.months;
UPDATE yourtable
SET number = (percentage * prev)
WHERE CURRENT of cur;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
用这两个来调用
SELECT update_numbers();
更新示例表的所有行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。