Найти запрос, который вычисляет время между первым и вторым порядком набора данных электронной торговли - PullRequest
0 голосов
/ 11 января 2020

Я пытаюсь вычислить время между первым и вторым заказом в моей таблице электронной торговли (заказы) для каждого клиента. enter image description here

Я нашел этот документ полезным для выбора всех верхних n строк в группе, но я не уверен, как связать его с вычислением времени второго порядка - время первого заказа https://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

Вот что я написал до сих пор:

SELECT customer_id, datediff(day, min(order_time), max(order_time)) 
     as avg_time
FROM ORDERS AS so
WHERE 
(select count(*) from ORDERS as se
   where se.customer_ID = so.customer_ID and se.order_time <= so.order_time
) <= 2
group by customer_id
having count(distinct order_time)>1
order by avg_time desc) t 

Однако, это неправильно, потому что он вычисляет максимум в начале из весь набор данных, который будет последним заказом, а не вторым.

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 11 января 2020

Как уже упоминалось, функции LAG / LEAD дадут вам то, что вам нужно здесь. Я предполагаю, что вы хотите это для каждого клиента.

 SELECT "Customer ID"
       ,"Transaction ID"
       ,"SKU"
       ,"Date"
       ,LAG("Date") OVER (PARTITION BY "Customer ID" ORDER BY "Date") AS LastOrderDate
       ,DATEDIFF(dd, LAG("Date") OVER (PARTITION BY "Customer ID" ORDER BY "Date"), "Date") AS DaysBetweenOrders
FROM ORDERS
;
1 голос
/ 11 января 2020

Итак, учитывая следующее в postgres (которое у меня есть в наличии):

so1=# SELECT * FROM table1;
 cust | tx  | sku |        _date        
------+-----+-----+---------------------
    1 | 111 |   3 | 2010-01-01 12:30:00
    2 | 222 |   1 | 2010-01-01 11:00:00
    2 | 222 |   2 | 2010-01-01 11:00:00
    3 | 333 |   7 | 2010-01-03 15:00:00
    1 | 444 |   8 | 2010-01-04 21:00:00
(5 rows)

Следующее позволяет выполнять арифметику даты c в последовательных строках (по дате)

so1=# SELECT
so1-#     fst - snd
so1-# FROM (
so1(#     SELECT
so1(#         _date AS fst,
so1(#         lag(_date, 1) OVER (ORDER BY _date) AS snd
so1(#     FROM
so1(#         table1) AS s;
    ?column?     
-----------------

 00:00:00
 01:30:00
 2 days 02:30:00
 1 day 06:00:00
(5 rows)


...