【问题标题】:Calculate the total number of orders by new users in last 29 days using SQLite使用 SQLite 计算过去 29 天内新用户的订单总数
【发布时间】:2019-04-29 03:45:06
【问题描述】:

一个 csv 文件包含“user_ids”和“order_dates”。一个用户可能有多个订单日期,但不能在同一天。确定新用户在使用产品后的前 29 天内下的订单总数。用户最早的订单输入 = 第 1 天。

例如:用户在 2018 年 1 月 1 日首次购买;在 2018 年 1 月 29 日之前下达的任何额外订单都将被计算在内。之后的任何订单历史记录均不予考虑。

我使用了 SQL fiddle,并且在获得返回给我的订单计数方面取得了进展。但是,返回的结果仅限于要求的 29 天内。

使用 between 子句应该将查询限制为在每个用户的前 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 个

【问题讨论】:

  • 如何定义new 用户?

标签: sql sqlite


【解决方案1】:

注意:以下需要 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);

【讨论】:

    【解决方案2】:

    使用此查询:

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

    您可以获得每个用户的第一个订单日期。
    您所要做的就是将它加入到表中:

    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
    

    请注意,我将条件从 &lt;= 29 更改为 &lt; 29
    因为您真正想要的是日期之间的最大距离
    为 28 天,例如 2018-01-012018-01-29,即 29 - 1 = 28
    请参阅demo
    结果:

    | user_id | total |
    | ------- | ----- |
    | 5962    | 1     |
    | 5963    | 2     |
    

    【讨论】:

      【解决方案3】:
      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;
      

      【讨论】:

      • 好收获。语法错误在原始查询中并被复制以进行编辑。我已经更正了我的答案语法。
      • 我显然很难在早上喝咖啡前数括号。后续编辑应该更符合您的喜好。 :)
      • 是的,看起来更好。
      猜你喜欢
      • 2019-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多