使用 RANGE 窗口框架子句将 SUM 分析函数从 PostgreSQL 移动到 Redshift

问题描述 投票:0回答:2

我在 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 相同结果的公式。

到目前为止我尝试过的:

  1. 没有 ORDER BY

  2. 带有框架“ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW”

  3. 带有框架“ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING”

我对每个选项都有不同的结果,并且没有一个与 PostgreSQL 解决方案匹配。

那么,我必须如何处理这个公式才能在 PostgreSQL 和 Redshift 上获得相同的结果?

postgresql amazon-redshift
2个回答
0
投票

在 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

-1
投票

只需删除“order by a.id”子句即可。以什么顺序对值进行求和并不重要。

© www.soinside.com 2019 - 2024. All rights reserved.