2012-09-12 52 views
0

我有一個窗口函數,它使用rank()操作將最新的DHCP日誌事件與IP地址相關聯,以將IP與主機名關聯。問題是查詢不能很好地擴展到大數據集,因此我想嘗試按照組來重寫它,但是我沒有成功。使用rank()根據組重寫窗口函數

create table large_table as 
select column1, column2, column3, column4, column5, column6 
from 
(
    select 
    a.column1, a.column2, a.start_time, 
    rank() OVER( 
     PARTITION BY a.column2, a.column1 order by a.start_time DESC 
    ) as rank, 
    last_value(a.column3) OVER (
     PARTITION BY a.column2, a.column1 order by a.start_time ASC 
     RANGE BETWEEN unbounded preceding and unbounded following 
    ) as column3, 
    a.column4, a.column5, a.column6 
    from 
    (table2 s 
     INNER JOIN table3 t 
     ON s.column2=t.column2 and s.event_time > t.start_time 
    ) a 
) b 
where rank =1; 

問題1: 我們如何通過窗口功能,而不是使用重寫基的上面查詢?

+0

該查詢是否必須完全匹配輸出?你能否爲表格和專欄提供一些有意義的名字,以便我們更好地掌握問題。 –

+0

您需要爲'table2'和'table3'提供表定義列的來源隱藏在(完全沒有意義的)子查詢'a'中。 –

+0

@ErwinBrandstetter:你的嘗試是合理的(briljant逆向工程),但似乎缺乏lag(1)結果。 – wildplasser

回答

1

我不認爲這樣做是一個成功的策略,以這種方式編寫窗口作爲分組。當您將表中的聚合連接到主表時,這會導致嚴重的性能問題。

更好的方法是使用plpgsql和一個在循環內添加窗口信息的函數。例如,ROWNUMBER可以添加這樣的:

CREATE OR REPLACE FUNCTION foo_with_rownumber() RETURNS SETOF foo_with_rownumber 
LANGUAGE PLPGSQL AS $$ 
DECLARE out_val foo_with_rownumber; 
     iter int; 
BEGIN 
    iter := 1; 
    FOR out_val IN select f.*, 0 FROM foo order by bar 
    LOOP 
     out_val.rownumber = iter; 
     return next out_val; 
     iter := iter + 1; 
    END LOOP; 
END; 
$$; 

秩()只會稍微複雜一些補充所以這應該讓你去是。