Рассчитайте общее количество заказов новых пользователей за последние 29 дней, используя SQLite - PullRequest
0 голосов
/ 29 апреля 2019

CSV-файл содержит «user_ids» и «order_dates».У пользователя может быть более 1 даты заказа, но не в тот же день.Определите общее количество заказов, размещенных новыми пользователями в течение первых 29 дней использования продукта.Самая ранняя запись заказа пользователя = день 1.

Пример: пользователь совершает свою первую покупку 2018-01-01;любые дополнительные заказы, размещенные до 2018-01-29 включительно, подсчитываются.Любая история заказов после этого не должна рассматриваться.

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

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

CREATE TABLE mytable
  (
   user_id int,
   order_date Date
  );

    INSERT INTO mytable(user_id,order_date) VALUES (5963,'2018-01-01');
    INSERT INTO mytable(user_id,order_date) VALUES (5963,'2018-01-29');
    INSERT INTO mytable(user_id,order_date) VALUES (5963,'2018-01-30');
    INSERT INTO mytable(user_id,order_date) VALUES (5962,'2018-01-01');
    INSERT INTO mytable(user_id,order_date) VALUES (5962,'2018-02-25');
    INSERT INTO mytable(user_id,order_date) VALUES (5962,'2018-04-03');
SELECT 
  user_id, 
  COUNT(order_date) AS total_orders

FROM 
  mytable 

GROUP BY 1

having 
  ROUND(julianday(order_date) - julianday(MIN(order_date))) <= 29 

order by 1 desc;

В вышеприведенном коде:

  • user_id = 5963: возвращает 3 итоговых заказа, ожидается 2.
  • user_id = 5962: возвращает 3общее количество заказов, ожидаемое 1

Ответы [ 3 ]

0 голосов
/ 29 апреля 2019

Примечание: для следующего требуется Sqlite 3.25 или новее, поскольку он использует оконную функцию:

WITH cte AS (
 SELECT user_id, order_date
      , date(first_value(order_date) OVER (PARTITION BY user_id ORDER BY order_date)
           , '+29 days') AS cutoff_date
 FROM mytable)
SELECT user_id, count(order_date) AS total_orders
FROM cte
WHERE order_date < cutoff_date
GROUP BY user_id
ORDER BY user_id;

На ваших данных образца это дает:

user_id     total_orders
----------  ------------
5962        1           
5963        2          

При частом запуске рассмотрите возможность добавления индекса:

CREATE INDEX mytable_idx_uid_order ON mytable(user_id, order_date);
0 голосов
/ 29 апреля 2019

С помощью этого запроса:

select user_id, min(order_date) mindate
from mytable 
group by user_id

вы можете получить 1-ую дату заказа для каждого пользователя.Все, что вам нужно сделать, это присоединить его к таблице:

select 
  m.user_id,
  count(*) total
from mytable m inner join (
  select user_id, min(order_date) mindate
  from mytable 
  group by user_id
) g on g.user_id = m.user_id
where round(julianday(m.order_date) - julianday(g.mindate)) < 29 
group by m.user_id

Обратите внимание, что я изменил условие с <= 29 на < 29,потому что то, что вы действительно хотите, это максимальное расстояние между датамибыть 28 дней, как 2018-01-01 до 2018-01-29, что 29 - 1 = 28.Смотрите демо .Результаты:

| user_id | total |
| ------- | ----- |
| 5962    | 1     |
| 5963    | 2     |
0 голосов
/ 29 апреля 2019
SELECT 
mytable.user_id, 
  COUNT (mytable.order_date) AS total_orders

FROM 
  mytable 

INNER JOIN (SELECT user_id, MIN(order_date) AS order_date FROM mytable GROUP BY user_id) AS earliest
ON mytable.user_id = earliest.user_id

WHERE ROUND(julianday(mytable.order_date) - julianday(earliest.order_date)) < 29 

GROUP BY mytable.user_id

ORDER BY COUNT(mytable.order_date) desc;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...