Заполните один столбец на основе предыдущих значений другого - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь создать столбец, который заполняет идентификатор транзакции для каждой строки до строки, в которой эта транзакция была завершена - в этом примере каждое событие «добавить в корзину» перед заказом.

Пока что Я пытался использовать FIRST_VALUE:

SELECT 
UserID, date, session_id, hitnumber, add_to_basket, transactionid, 
first_value(transactionid) over (partition by trans_part order by date, transactionid) AS t_id
FROM(
  select UserID, date, session_id, hitnumber, add_to_basket, transactionid, 
  SUM(CASE WHEN transactionid IS NULL THEN 0 ELSE 1 END) OVER (ORDER BY date, transactionid) AS trans_part,
  FIRST_VALUE(transactionid IGNORE NULLS) 
OVER (PARTITION BY userid ORDER BY hitnumber ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS t_id,
  from q1
  join q2 using (session_id)
  order by 1,2,3,4
)

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

Как я могу изменить свой код, чтобы я мог видеть идентификатор транзакции заказа ПОСЛЕ событий корзины, которые привели к нему? Например, в таблице ниже я хочу видеть идентификатор транзакции, заканчивающийся на ... 095 вместо идентификатора, заканчивающегося на ... 383 для столбца t_id.

enter image description here

Основываясь на ответе Гордона, приведенном ниже, я также попытался:

last_value(transactionid ignore nulls) over(
  order by hitnumber 
  rows between unbounded preceding and current row) as t_id2,

Но это не заполнение строк событий, которые выполняют транзакцию с идентификатором транзакции (рассматривается ниже как t_id2 ): enter image description here

1 Ответ

1 голос
/ 02 апреля 2020

Вы можете использовать last_value(ignore nulls):

select . . . ,
       last_value(transaction_id ignore nulls) over (
           order by hitnumber
           rows between unbounded preceding and current row
          ) as t_id
from q1 join
     q2 using (session_id);

Отличие от вашего ответа заключается в предложении окон, которое заканчивается в текущей строке.

РЕДАКТИРОВАТЬ:

Это похоже, что есть один t_id на session_id, поэтому просто используйте max():

select . . . ,
       max(transaction_id) over (partition by session_id) as t_id
from q1 join
     q2 using (session_id);
...