2014-01-28 3 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, а затем по окончанию, чтобы я вернулся:

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 ; 

То, что я изначально есть таблица идентификатора отображается на сегодняшний день. Чтобы вычислить количество дней между двумя последовательными днями, я запускаю этот запрос:

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 EndDate» в конце запроса, в противном случае порядок строк является то, что Postgres чувствует, что дает вам.

ORDER BY в вашем предложении OVER управляет только тем, как row_number() видит данные, а не как данные в конечном итоге возвращаются.

+0

Я понимаю, что, однако, порядок по-прежнему не видит данных правильно. Он заказал его по столбцу, который я попросил его разделить. – mskem

Смежные вопросы