2015-02-15 3 views
1

Я использую Redshift (Postgres) и Pandas для выполнения своей работы. Я пытаюсь получить количество пользовательских действий, позволяет делать покупки, чтобы их было легче понять. У меня есть таблица, покупки, которая содержит следующие данные:Как найти количество покупок с интервалом по времени? SQL

user_id, timestamp , price 
1,  , 2015-02-01, 200 
1,  , 2015-02-02, 50 
1,  , 2015-02-10, 75 

в конечном счете, я хотел бы количество покупок в течение определенных меток времени. Такие, как

userid, 28-14_days, 14-7_days, 7 

Вот то, что я до сих пор, я знаю, у меня нет верхнего предела на даты:

SELECT DISTINCT x_days.user_id, SUM(x_days.purchases) AS x_num, SUM(y_days.purchases) AS y_num, 
x_days.x_date, y_days.y_date 
FROM 
(
SELECT purchases.user_id, COUNT(purchases.user_id) as purchases, 
            DATE(purchases.timestamp) as x_date 
FROM purchases 
WHERE purchases.timestamp > (current_date - INTERVAL '%(x_days_ago)s day') AND 
purchases.max_value > 200 
GROUP BY DATE(purchases.timestamp), purchases.user_id 
) AS x_days 
JOIN 
(
    SELECT purchases.user_id, COUNT(purchases.user_id) as purchases, 
            DATE(purchases.timestamp) as y_date 
    FROM purchases 
    WHERE purchases.timestamp > (current_date - INTERVAL '%(y_days_ago)s day') AND 
    purchases.max_value > 200 
    GROUP BY DATE(purchases.timestamp), purchases.user_id) AS y_days 
    ON 
    x_days.user_id = y_days.user_id 
GROUP BY 
x_days.user_id, x_days.x_date, y_days.y_date 

params={'x_days_ago':x_days_ago, 'y_days_ago':y_days_ago} 
where these are set in python/pandas 

x_days_ago = 14 y_days_ago = 7

Но это не сработало так, как планировалось:

user_id x_num y_num x_date  y_date 
0 5451772 1  1  2015-02-10 2015-02-10 
1 5026678 1  1  2015-02-09 2015-02-09 
2 6337993 2  1  2015-02-14 2015-02-13 
3 6204432 1  3  2015-02-10 2015-02-11 
4 3417539 1  1  2015-02-11 2015-02-11 

Даже если у меня нет верхний д (так что x эффективно выполняет поиск с 14 дней до настоящего момента, а y составляет 7 дней, что означает совпадение), в некоторых случаях y выше.

Может ли кто-нибудь помочь мне исправить это или дать мне лучший способ?

Спасибо!

ответ

1

Это может быть не самым эффективным ответом, но вы можете создать каждую сумму с суб-выбора:

WITH 
    summed AS (
    SELECT user_id, day, COUNT(1) AS purchases 
     FROM (SELECT user_id, DATE(timestamp) AS day FROM purchases) AS _ 
    GROUP BY user_id, day 
), 
    users AS (SELECT DISTINCT user_id FROM purchases) 
SELECT user_id, 
     (SELECT SUM(purchases) FROM summed 
     WHERE summed.user_id = users.user_id 
      AND day >= DATE(NOW() - interval ' 7 days')) AS days_7, 
     (SELECT SUM(purchases) FROM summed 
     WHERE summed.user_id = users.user_id 
      AND day >= DATE(NOW() - interval '14 days')) AS days_14 
    FROM users; 

(Это было проверено в Postgres, а не в Redshift, но документация Redshift предполагает, что оба WITH и DISTINCT.) Мне бы хотелось сделать это с помощью окна, чтобы получить скользящие суммы; но это немного обременительно без generate_series().

+0

Спасибо @solidsnack, но в соответствии с http://docs.aws.amazon.com/redshift/latest/dg/c_redshift-sql-implementated-differently.html redshift не поддерживает WITH – Ajax729

+0

В нем говорится, что 'WITH' is не поддерживается в сочетании с 'INSERT',' DELETE' и 'UPDATE'. См. Документы для 'WITH' под' SELECT': http://docs.aws.amazon.com/redshift/latest/dg/r_WITH_clause.html «Предложение WITH» - это необязательное предложение, которое предшествует списку SELECT в запросе. " – solidsnack

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