Redshift - оконная функция - получить статистику за предыдущий час для каждой строки - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь написать запрос для Redshift на основе заказов на продукцию. Таблица содержит столбцы, такие как store_id, order_number, order_datetime, products_ordered, order_time. Запрос, который я пытаюсь написать, выбрал бы из этой таблицы, и для каждой строки он включал бы некоторую статистику, основанную на предыдущем часе заказов в этом магазине.

В настоящее время я могу сделать что-то вроде:

SELECT store_id, order_number, order_datetime, products_ordered, order_time,
       (SELECT COUNT(*) FROM mtable WHERE store_id=o.store_id AND order_time BETWEEN (o.order_time - interval '1 hour') AND o.order_time) as prev_num_orders,
       (SELECT AVG(products_ordered) FROM mtable WHERE store_id=o.store_id AND order_time BETWEEN (o.order_time - interval '1 hour') AND o.order_time) as prev_avg_orders
FROM mtable o;

Производительность на этом ужасна. Одна из основных причин, вероятно, заключается в том, что мне приходится дважды просматривать заказы предыдущих часов, чтобы получить две разные характеристики. Есть ли способ оптимизировать это? Я думаю, что должна быть функция окна, но я не уверен.

Ответы [ 2 ]

1 голос
/ 14 января 2020

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

SELECT store_id, 
       order_number, 
       order_datetime, 
       products_ordered, 
       order_time, 
       COUNT(prev_orders.store_id) prev_num_orders,
       AVG(prev_orders.products_ordered)  prev_avg_orders
FROM mtable o
left join mtable prev_orders on prev_orders.store_id=o.store_id 
                            AND prev_orders.order_time BETWEEN (o.order_time - interval '1 hour') AND o.order_time 
--and o.order_number != prev_orders.order_number
group by store_id, 
       order_number, 
       order_datetime, 
       products_ordered, 
       order_time;

Обратите внимание, что статистика столбцов prev_num_orders и prev_avg_orders c также будет включать текущий порядок . Для исключения текущего заказа из статистики откомментируйте строку сравнения номера заказа из оператора SQL.

0 голосов
/ 14 января 2020

У меня нет данных для тестирования производительности, но когда я столкнулся с подобной проблемой в Redshift, я сделал следующее:

    with cte as
    (
    SELECT store_id, order_number, order_datetime, products_ordered, order_time,
    LAG (products_ordered,1) OVER (PARTITION BY store_id ORDER BY order_time) AS prev_products_ordered
    from mtable
    )
    select store_id, order_number, order_datetime, products_ordered, order_time,
    count(*) as prev_num_orders, avg(prev_products_ordered) as prev_avg_orders 
from cte
    group by store_id, order_number, order_datetime, products_ordered, order_time
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...