我尝试将我在代码中的内容实现为postgres查询。 以下示例并不完全是我们尝试做的事情,但我希望它能说明我是如何尝试使用之前计算出的行中的值的。
示例表,以帮助我演示我尝试做的事情:
test=# select * from test ;
id | field1 | field2 | field3 | score
----+--------+--------+--------+-------
1 | 1 | 3 | 2 | 1.25
2 | 1 | -1 | 1 |
3 | 2 | 1 | 5 |
4 | 3 | -2 | 4 |
这是正在进行的查询:
select id,
coalesce (
score,
case when lag_field3 = 2 then 0.25*(3*field1+field2) end
) as new_score
from (
select id, field1, field2, field3, score,
lag (field3) over (order by id) as lag_field3
from test
) inner1 ;
到目前为止返回我想要的内容......
id | new_score
----+-----------
1 | 1.25
2 | 0.5
3 |
4 |
查询的下一次迭代:
select id,
coalesce (
score,
case when lag_field3 = 2 then 0.25*(3*field1+field2) end,
case when field1 = 2 then 0.75 * lag (new_score) end
) as new_score
from (
select id, field1, field2, field3, score,
lag (field3) over (order by id) as lag_field3
from test
) inner1 ;
区别在于:
case when field1 = 2 then 0.75 * lag (new_score) end
我知道并理解为什么这不起作用。
我将计算字段别名为new_score,而当field1 = 2时,我想要0.75 *之前的行new_score值。 我知道new_score是一个别名,无法使用。
我有什么方法可以做到这一点吗?我可以尝试复制该表达式,在其周围包含一个滞后,将其作为别的东西,并尝试使用它,但这会变得非常混乱。
有什么想法吗?
非常感谢。
答案 0 :(得分:0)
Postgres允许您在CASE
语句中使用窗口。可能你错过了OVER (ORDER BY id)
部分。您还可以定义不同的窗口,但不能将窗口与GROUP BY
结合使用。此外,它不会让你使用ann窗口,所以你必须写下一些子查询或CTE。
以下是查询:
SELECT id, COALESCE(tmp_score,
CASE
WHEN field1 = 2
THEN 0.75 * LAG(tmp_score) OVER (ORDER BY id)
-- missing ELSE statement here
END
) AS new_score
FROM (
SELECT id, field1,
COALESCE (
score,
CASE
WHEN LAG(field3) OVER (ORDER BY id) = 2
THEN 0.25*(3*field1+field2)
END
) AS tmp_score
FROM test
) inner1
创建和填充表格的代码:
CREATE TABLE test(
id int,
field1 int,
field2 int,
field3 int,
score numeric
);
INSERT INTO test VALUES
(1, 1, 3, 2, 1.25),
(2, 1, -1, 1, NULL),
(3, 2, 1, 5, NULL),
(4, 3, -2, 4, NULL);
查询返回此输出:
id | new_score
----+-----------
1 | 1.25
2 | 0.50
3 | 0.3750
4 |