我在 PostgreSQL 中有以下代码,我需要在 Amazon Redshift 上重现该代码:
select *
from
(
select distinct
a.id
, sum(case when a.is_batch_empty then 1 else 0 end) over (partition by a.client_id order by a.id) as empty_count
from my_temp_table a
) a
where a.id = 111
在 Amazon Redshift 中,此代码执行失败并出现以下错误:
带有
子句的聚合窗口函数需要框架子句ORDER BY
因此,在 Redshift 上,我需要添加
ROWS BETWEEN
部分。
问题是我找不到给出与 PostgreSQL 相同结果的公式。
到目前为止我尝试过的:
没有 ORDER BY
带有框架“ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW”
带有框架“ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING”
我对每个选项都有不同的结果,并且没有一个与 PostgreSQL 解决方案匹配。
那么,我必须如何处理这个公式才能在 PostgreSQL 和 Redshift 上获得相同的结果?
在 PostgreSQL 中,窗口规范中的
order by
意味着 between unbounded preceding and current row
框架子句。如果删除 order by
,框架将跨越整个分区。 引用文档:
使用
,这会将框架设置为从分区开始到当前行的最后一个ORDER BY
对等点的所有行。如果没有ORDER BY
,这意味着分区的所有行都包含在窗口框架中,因为所有行都成为当前行的对等行。ORDER BY
这在您要查找的内容之后提到:
默认的取景选项是
,与RANGE UNBOUNDED PRECEDING
相同。RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
您的第二次尝试是最接近的,但请注意,默认值是
RANGE
,而不是 ROWS
和 我在 Redshift 窗口函数文档中没有看到
RANGE
。如果 a.id
不唯一,结果将会有所不同 如此处所示。
您可以尝试使用相关的
标量子查询来模拟
RANGE
框架子句行为:
select distinct a.id,
(select sum(case when t2.is_batch_empty then 1 else 0 end)
from my_temp_table t2
where a.client_id=t2.client_id
and a.id>=t2.id)
from my_temp_table a
只需删除“order by a.id”子句即可。以什么顺序对值进行求和并不重要。