如何使用MySQL进行队列分析?

如何使用MySQL进行队列分析?,mysql,sql,Mysql,Sql,以下是我当前的查询: SELECT DATEDIFF(created_at, '2020-07-01') DIV 6 period, user_id FROM transactions WHERE DATE(created_at) >= '2020-07-01' GROUP BY user_id, DATEDIFF(created_at, '2020-07-01') DIV 6 ORDER BY period 它返回每个期间至少有一个事务的用户列表===6天。以下是电流

以下是我当前的查询:

SELECT DATEDIFF(created_at, '2020-07-01') DIV 6 period, 
       user_id FROM transactions
WHERE DATE(created_at) >= '2020-07-01' 
GROUP BY user_id, DATEDIFF(created_at, '2020-07-01') DIV 6
ORDER BY period
它返回每个期间至少有一个事务的用户列表===6天。以下是电流输出的简化示例:

现在,我需要知道,在哪个时期,有多少用户至少有一次交易,在市场营销的术语中,我试图通过队列图来描绘保留率。因此,计算必须采用笛卡尔算法;就像一个自我加入

以下是预期结果:


纯粹使用MySQL是否可以做到这一点?

您可以使用窗口函数:

SELECT first_period, period, COUNT(*),
       COUNT(*) / SUM(COUNT(*)) OVER (PARTITION BY first_period) as ratio
FROM (SELECT DATEDIFF(created_at, '2020-07-01') DIV 6 period, 
            user_id,
            MIN(MIN(DATEDIFF(created_at, '2020-07-01') DIV 6) OVER (PARTITION BY user_id)) as first_period
     FROM transactions
     WHERE DATE(created_at) >= '2020-07-01' 
     GROUP BY user_id, DATEDIFF(created_at, '2020-07-01') DIV 6
    ) u
GROUP BY first_period, period
ORDER BY first_period, period;
这不包括缺少的时段。这是一个小把戏,因为您需要列举所有这些把戏:

with periods as (
      select 0 as period union all
      select 1 as period union all
      select 2 as period
     )
select p1.period, p2.period, COUNT(u.user_id)
from periods p1 join
     periods p2
     on p1.period <= p2.period left join
     (SELECT DATEDIFF(created_at, '2020-07-01') DIV 6 period, 
             user_id,
             MIN(MIN(DATEDIFF(created_at, '2020-07-01') DIV 6) OVER (PARTITION BY user_id)) as first_period
      FROM transactions
      WHERE DATE(created_at) >= '2020-07-01' 
      GROUP BY user_id, DATEDIFF(created_at, '2020-07-01') DIV 6
     ) u
     ON p1.period = u.first_period AND p2.period = u.period
GROUP BY p1.period, p2.period;

1064-您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,以了解在第行DATEcreated处>='202'处的事务中使用“作为第一个\u期间”附近的正确语法5@MartinAJ . . . 这是一个打字错误。1055-选择列表的表达式3不在GROUP BY子句中,并且包含未聚合的列“dbname.transactions.created_at”,该列在功能上不依赖GROUP BY子句中的列;这与sql\u mode=only\u full\u组不兼容_by@MartinAJ . . . 这一次,没有语法错误:。您的SQL非常好。。比每个人都高一级。。完全流利的概念和语法。。。完美的
SELECT first_period, period, COUNT(*),
       COUNT(*) / SUM(COUNT(*)) OVER (PARTITION BY first_period) as ratio
FROM (SELECT DATEDIFF(created_at, '2020-07-01') DIV 6 period, 
            user_id,
            MIN(MIN(DATEDIFF(created_at, '2020-07-01') DIV 6) OVER (PARTITION BY user_id)) as first_period
     FROM transactions
     WHERE DATE(created_at) >= '2020-07-01' 
     GROUP BY user_id, DATEDIFF(created_at, '2020-07-01') DIV 6
    ) u
GROUP BY first_period, period
ORDER BY first_period, period;
with periods as (
      select 0 as period union all
      select 1 as period union all
      select 2 as period
     )
select p1.period, p2.period, COUNT(u.user_id)
from periods p1 join
     periods p2
     on p1.period <= p2.period left join
     (SELECT DATEDIFF(created_at, '2020-07-01') DIV 6 period, 
             user_id,
             MIN(MIN(DATEDIFF(created_at, '2020-07-01') DIV 6) OVER (PARTITION BY user_id)) as first_period
      FROM transactions
      WHERE DATE(created_at) >= '2020-07-01' 
      GROUP BY user_id, DATEDIFF(created_at, '2020-07-01') DIV 6
     ) u
     ON p1.period = u.first_period AND p2.period = u.period
GROUP BY p1.period, p2.period;