用于漏斗分析的 SQL

Posted

技术标签:

【中文标题】用于漏斗分析的 SQL【英文标题】:SQL for funnel analysis 【发布时间】:2015-11-23 00:48:32 【问题描述】:

我有一个场景,人们可以采取行动 1 并纾困;或者 action1 & action2 & bail out,或者他们可以做 action1,action2 然后说“我想玩更多”。我想查找每个级别的人数: - 采取行动1 - 做了 action1 和 action2 - 做了action1和action2,还说“我想玩更多”

每次用户执行操作时,我们都会记录一个 sessionId。因此,如果用户运行操作 1 和操作 2,我们将有两行具有相同的会话 ID、相同的客户 ID 和不同的操作。

╔══════════════════════════════════════╦════════════════╦════════╗
║              SessionId               ║ FirstRunAction ║ UserId ║
╠══════════════════════════════════════╬════════════════╬════════╣
║ 039af321-457e-41a6-b303-41ca935b0877 ║ action_1       ║ eb6    ║
║ 039af321-457e-41a6-b303-41ca935b0877 ║ action_2       ║ eb6    ║
╚══════════════════════════════════════╩════════════════╩════════╝

以上数据在一张表中。 Action1 和 action2 在 UserAction 表中,但“我想玩更多”在名为“Play”表的单独表中。

我做了以下,但它不正确。

我想要一个 if 类型的逻辑。仅当操作 1 存在时才搜索操作 2 并搜索 当该会话还具有 action1 和 action2 时,“我想玩更多”。我在下面写了一个,但不知道如何在任何级别存储结果以及我所做的是否正确。我有 600 万个数据开始。有什么帮助吗?

Action1Results = SELECT [SessionId]  
                        ,[Action]  
                        ,[UserId]  
                 FROM [Test].[dbo].[UserAction]  
                 WHERE [Action] = 'action_1';  

Action2Results = SELECT [SessionId]  
                        ,[Action]  
                        ,[UserId]  
                 FROM [Test].[dbo].[UserAction]   
                 WHERE [Action] = 'action_2';      

PlayMoreResults = SELECT [SessionId]  
                        ,[Play]  
                        ,[UserId]  
                 FROM [Test].[dbo].[UserPlay]  
                 WHERE [Play] = 'I want to play more';  

FinalResults = SELECT [SessionId]  
                     ,[UserId]  
                 FROM [Test].[dbo].[Action] with (nolock)   
                 INNER JOIN [Test].[dbo].[UserPlay] with (nolock)   
                 ON [Test].[dbo].[UserPlay].SessionId = [Test].[dbo].[Action].SessionId;  

实际上可能有很多动作,但它们总是以 _1 和 _2 结尾。操作列表可能会随着时间而改变。

例如我可以采取以下行动:

“Write_1”、“Write_2”、“Birds_1”、“Birds_2”、“Pen_1”、“Pen_2”。

所以对于这些,我必须看看有多少

'Write_1" -> "Write_2" -> '我想玩更多'',

那么有多少

'Birds_1" -> "Birds_2" -> '我想玩更多'',

那么有多少

'Pen_1" -> "Pen_2" -> '我想玩更多''

等等。所以漏斗为每种类型。

【问题讨论】:

请提供更多细节。你用的是 mysql 还是 SQLserver 什么数据库? 公平的问题@davejal 除了 [dbo] 有点放弃(MS Sql 服务器):) 谢谢胡安。实际上可能有很多动作,但它们总是有 _1 和 _2。操作列表可能会随着时间而改变。例如。我可以执行以下操作:“Write_1”、“Write_2”、“Birds_1”、“Birds_2”、“Pen_1”、“Pen_2”。因此,对于这些,我必须查看“Write_1”->“Write_2”->“我想玩更多”有多少,然后“Birds_1”->“Birds_2”->“我想玩更多”有多少',然后'Pen_1" -> "Pen_2" -> 'I want to play more'' 等有多少。所以每个类型的漏斗。 如果你不输入@Juan 我不会收到通知。所以你想要 count(write_1) 和 count(write_1 + write_2) 和 count (write_1+ write_2+ want to play) 一样的鸟,笔?如果一个人有write_1 + write_2 也算write_1 ? @Juan 对不起。我是新来的。我发布了另一个更详细的问题。另外,我不知道如何附加一个 excel 文件来向您展示示例数据集。 ***.com/questions/33926868/… 【参考方案1】:

我认为行动只能是 ('action_1','action_2') other wise you have to compare for those value on theON-WHEREand theCASE`

SqlFiddle Demo

WITH CTE as (
     SELECT UA1.SessionID, 
            UA1.UserId, 
            UA1.FirstRunAction Action1,
            UA2.FirstRunAction Action2,
            UP.Play Action3
     FROM UserAction UA1
     LEFT JOIN UserAction UA2
            ON UA1.SessionID = UA2.SessionID
           AND UA2.UserId = UA2.UserId
           AND UA1.FirstRunAction <> UA2.FirstRunAction           
     LEFT JOIN UserPlay UP
            ON UA1.SessionID = UP.SessionID
           AND UA2.UserId = UP.UserId
     WHERE UA1.FirstRunAction = 'action_1'
), classify as (
SELECT CASE 
           WHEN Action3 IS NOT NULL AND Action3 = 'I want to play more' THEN 'TYPE 3'
           WHEN Action2 IS NOT NULL THEN 'TYPE 2'
           WHEN Action1 IS NOT NULL THEN 'TYPE 1'
           ELSE 'TYPE 0'
       END as actionType
FROM cte 
)
SELECT actionType, count(*)
FROM classify
GROUP BY actionType

CTE 部分输出

| SessionID | UserId |  Action1 |  Action2 |             Action3 |
|-----------|--------|----------|----------|---------------------|
|         1 |      1 | action_1 | action_2 | I want to play more |
|         2 |      2 | action_1 |   (null) |              (null) |
|         3 |      3 | action_1 | action_2 |          Don’t Know |
|         4 |      4 | action_1 |   (null) |              (null) |
|         5 |      5 | action_1 | action_2 |              (null) |
所以UserID = 1 的所有三个动作都是type3 UserID = (2, 4) 只有一个动作是 type1 UserID = 3 有 3 个动作,但最后一个不是 I want to play more 类型 2 也是 UserID = 5

最终输出

| actionType |   |
|------------|---|
|     TYPE 1 | 2 |
|     TYPE 2 | 2 |
|     TYPE 3 | 1 |

如果您有一张表 USERS,您可以从该表开始,因此还可以计算有多少用户拥有 TYPE 0

【讨论】:

谢谢胡安。实际上可能有很多动作,但它们总是有 _1 和 _2。操作列表可能会随着时间而改变。例如。我可以采取以下行动: 我没有看到这个例子,你能详细说明这个问题吗?我回答你提出的问题,如果你不提供样本数据和期望输出,很难给你答案。【参考方案2】:

这应该会按每个 session_category 为您提供不同用户的计数 -

  3 = I want to play more
  2 = action_1, and action_2
  1 = action_1

请注意,如果用户实际上一次只执行 action_1,而另一次执行 action_1+action_2,这将在 session_categories 中多次计算用户。你没有解释你打算如何处理这种情况(除非我错过了什么)。

https://gist.github.com/leonpanokarren/56f313130118dad47113

我尝试将这个查询内联粘贴在这里无数次,但都是徒劳的。

【讨论】:

以上是关于用于漏斗分析的 SQL的主要内容,如果未能解决你的问题,请参考以下文章

Excel-漏斗图分析(差异分析)

谷歌分析:漏斗在类别标签和操作中添加啥

Clickhouse(流量分析(一).漏斗分析案例)

思迈特软件深度讲解:数据分析模型之漏斗分析

漏斗思维

干货分享 | 看如何用Python数据可视化来分析用户留存率,建议收藏