0

我有在紅移這種運行總和的問題(使用的Postgres 8):計算在一個窗口函數運行總和

select extract(month from registration_time) as month 
, extract(week from registration_time)%4+1 as week 
, extract(day from registration_time) as day 
, count(*) as count_of_users_registered 
, sum(count(*)) over (ORDER BY (1,2,3)) 
from loyalty.v_user 
group by 1,2,3 
order by 1,2,3 
; 

我得到的錯誤是:

ERROR: 42601: Aggregate window functions with an ORDER BY clause require a frame clause 
+2

您不能在一個窗口定義中使用的列數的順序(和'(1,2,3)'是什麼不同於'1,2,3' - 不要使用無用的括號)。 'over(order by registration_time)'應該做你想做的事 –

+0

使用'order by registration_time'仍然會出現同樣的錯誤。我的sum函數本身的語法是正確的嗎? – simplycoding

回答

3

可以對同一查詢級別的聚合函數的結果運行一個窗口函數。這只是簡單得多的這種情況下使用子查詢:

SELECT *, sum(count_registered_users) OVER (ORDER BY month, week, day) AS running_sum 
FROM (
    SELECT extract(month FROM registration_time)::int  AS month 
     , extract(week FROM registration_time)::int%4+1 AS week 
     , extract(day FROM registration_time)::int  AS day 
     , count(*) AS count_registered_users 
    FROM loyalty.v_user 
    GROUP BY 1, 2, 3 
    ORDER BY 1, 2, 3 
    ) sub; 

我也是固定的表達計算week語法。 extract()返回double precision,但模運算符%不接受double precision數字。我將所有三個投入到integer,同時處於此狀態。

@a_horse commented一樣,不能在窗口函數的ORDER BY子句中使用位置引用(與查詢的ORDER BY子句不同)。

但是,您不能在此查詢中使用over (order by registration_time),因爲您正在按month,week,day進行分組。根據需要,registration_time既不合並,也不在GROUP BY子句中。在查詢評估的這個階段,您不能再訪問該列。

可以重複前三SELECT項目的表達式ORDER BY子句中,使其工作:

SELECT extract(month FROM registration_time)::int  AS month 
    , extract(week FROM registration_time)::int%4+1 AS week 
    , extract(day FROM registration_time)::int  AS day 
    , count(*) AS count_registered_users 
    , sum(count(*)) OVER (ORDER BY 
       extract(month FROM registration_time)::int 
      , extract(week FROM registration_time)::int%4+1 
      , extract(day FROM registration_time)::int) AS running_sum 
FROM loyalty.v_user 
GROUP BY 1, 2, 3 
ORDER BY 1, 2, 3; 

但似乎相當嘈雜。 (雖然性能會很好。)

另外:我想知道week%4+1背後的目的......整個查詢可能會更簡單。

相關:

+0

是的,你的回答和建議是有道理的。直到我嘗試在'按月,按周,按天排列的順序'之後包括'無界的前面的行'並且它工作之後,我纔得到相同的錯誤。因此,對於將來遇到這種情況的任何人來說,它看起來像'行前無界'或任何你想要的選項是必需的。再次,AWS文檔不清楚這一點,因爲這是在Redshift – simplycoding

+0

@simplycoding:Redshift是你應該提到的問題,因爲它不是Postgres。從中派生出來,但實質上有所不同。上面的代碼在Postgres中是這樣工作的,[quote](http://www.postgresql.org/docs/current/interactive/sql-expressions。html#SYNTAX-WINDOW-FUNCTIONS),'默認框架選項是RANGE UNBOUNDED PRECEDING'。 –