用于漏斗分析的SQL

时间:2015-11-23 00:48:33

标签: sql sql-server

我有一个场景,人们可以做出行动1并纾困;或者行动1& action2&拯救,或者他们可以做行动1,行动2&然后说“我想玩更多”。我想找到每个级别的人数:
- 行动1 - 动作1和动作2 - 动作1和动作2还说“我想玩更多”

每次用户执行操作时,我们都会记录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结尾。行动清单可能会随着时间而改变。

E.g。我可以采取以下行动:

  

'Write_1',“Write_2”,“Birds_1”,Birds_2“,”Pen_1“,”Pen_2“。

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

  

'Write_1' - >“Write_2” - >'我想要更多'',

然后有多少人

  

'Birds_1' - >“Birds_2” - >'我想要更多'',

然后有多少人

  

'Pen_1' - >“Pen_2” - >'我想要发挥更多''

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

2 个答案:

答案 0 :(得分:0)

我假设行动只能是('动作_ 1','action_2') other wise you have to compare for those value on the ON-WHERE and the CASE`

<强> 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 :(得分:0)

这应该为每个session_category -

提供不同用户的计数
param3.ne = "stuff"

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

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

我尝试将这个查询内联到这里几十万次徒劳无功。