2014-01-28 50 views
2

我上的Postgres 9.3.2訂貨工作,我有這個表:PostgreSQL的ROW_NUMBER不按日期

id startdate enddate no_of_days_between 

1 2010-12-22 2010-12-23 1 
1 2010-12-23 2010-12-24 1 
1 2010-12-24 2010-12-25 1 
1 2010-12-25 2010-12-26 1 
1 2010-12-26 2010-12-27 1 
1 2010-12-27 2010-12-28 1 
1 2010-12-28 2010-12-29 1 
1 2010-12-29 2011-03-06 67 
1 2011-03-06 2011-03-07 1 
1 2011-03-07 2011-03-08 1 
1 2011-03-08 2011-03-09 1 

,我想要做的就是找到連續數日連勝。對於這一點,我現在用的是ROW_NUMBER窗函數在此查詢:

select t.*, row_number() over (partition by no_of_days_between order by enddate) as no_of_consecutive_days from t 

什麼,我想回去是這樣的:

id startdate enddate no_of_days no_of_consecutive_days 
          _between 
1 2010-12-22 2010-12-23 1   1 
1 2010-12-23 2010-12-24 1   2 
1 2010-12-24 2010-12-25 1   3 
1 2010-12-25 2010-12-26 1   4 
1 2010-12-26 2010-12-27 1   5 
1 2010-12-27 2010-12-28 1   6 
1 2010-12-28 2010-12-29 1   7 
1 2010-12-29 2011-03-06 67   1 
1 2011-03-06 2011-03-07 1   1 
1 2011-03-07 2011-03-08 1   2 
1 2011-03-08 2011-03-09 1   3 

但查詢返回的是什麼更喜歡它首先由有序no_of_days_between然後通過enddate所以我回來了:

id startdate enddate no_of_days no_of_consecutive_days 
          _between 
1 2010-12-22 2010-12-23 1   1 
1 2010-12-23 2010-12-24 1   2 
1 2010-12-24 2010-12-25 1   3 
1 2010-12-25 2010-12-26 1   4 
1 2010-12-26 2010-12-27 1   5 
1 2010-12-27 2010-12-28 1   6 
1 2010-12-28 2010-12-29 1   7 
1 2011-03-06 2011-03-07 1   8 
1 2011-03-07 2011-03-08 1   9 
1 2011-03-08 2011-03-09 1   10 
1 2010-12-29 2011-03-06 67   1 

有沒有人遇到過這個問題呢?我怎樣才能強制它先訂購然後再分區?

感謝

回答

0

看來這是按照SQL標準預期的行爲。 我不得不寫一個函數來實現我想要它做的事 - 這是按日期排序的第一個分區,然後是分區。這意味着每次存在其他數字時,計數器都會重置。

這對於連續的連勝條件非常有用。

代碼到我的功能:

CREATE TYPE consecutive_length_type AS 
    (daystreak integer, 
    streakstart date, 
    streakend date; 

CREATE OR REPLACE FUNCTION get_maxconsecutive_day_streak() RETURNS consecutive_length_type AS 
$BODY$ 
declare 
    max_length integer := 0; 
    end_date date; 
    cons_days integer :=0; 
    return_rec consecutive_length_type; 
    rec record; 
begin 

for rec in 
    select * from table t --table as above 
loop 
    if rec.no_of_days_between = 1 then 
     cons_days := cons_days + 1 ; 
     if cons_days > max_length then 
      max_length := cons_days; 
      end_date := rec.enddate ; 
          --this way I can see when the streak ended 
     end if; 
    else 
     cons_days := 0; 
    end if; 
end loop; 


return_rec.daystreak := max_length; 
return_rec.streakend := end_date; 
return_rec.streakstart := end_date - max_length; 
         --I am calculating the day start so I can use it further on 

return return_rec; 
end; 
$BODY$ 
    LANGUAGE plpgsql ; 

我本來已經是映射到日期ID的表。爲了計算連續兩天之間的天數,我運行這個查詢:

select id , 
lag(date_logged,1,date_logged) over 
     (partition by id order by id, date_logged ) as startdate 
date_logged as enddate , 
date_logged- lag(date_logged,1,date_logged) over 
     (partition by id order by id, date_logged ) as no_of_days_between 
from table_name; 
2

您還需要有在您的查詢的末尾「ORDER BY結束日期」,行的,否則順序是什麼樣的Postgres給你的感覺。

OVER子句中的ORDER BY只控制row_number()如何查看數據,而不是數據如何最終返回。

+0

我明白,但是,順序仍然沒有看到數據的正確方法。它已按照我要求將其分區的列進行排序。 – mskem