2016-11-23 51 views
0

我正在尝试为网站流量构建灵活的归因模型。我开始制作最后一次点击模式,根据访问者在转换前最后一次访问的情况将转化归因于流量渠道。所以:在SQL Server 2012中选择满足条件x的最大值

Visitor  Visit  Channel ConversionId 
visitor a visit 1 email 123 
visitor a visit 2 email 123 
visitor a visit 3 direct 123 
visitor b visit 1 seo  123 
visitor b visit 2 direct 123 
visitor b visit 3 email 123 
visitor c visit 1 seo  123 
visitor c visit 2 direct 123 
visitor c visit 3 direct 123 

在上面的例子中,我会计算每个访问者的最终访问并将转换归因于该频道。因此,访问者a和访问者c的转化将归因于直接,而访问者b则归因于电子邮件。

现在我希望能够排除direct,并因此能够将转换归因于最后一个非直接渠道。在这种情况下,访客a和访客b的转化将归因于电子邮件(访客a的第三次访问将被排除),而访客c的转化将归因于se(因为c的第二次和第三次访问将被排除)。

我有这个成立至今的方式是(和一些这看上去有点愚蠢,因为我剥夺了一些连接和识别的简单信息出来):

WITH test (visitor, 
      visit, --a number unique for each visitor row but not necessarily unique across all visits 
      channel, 
      conversionid, 
      rn) AS 
(
SELECT visitorid AS visitor, 
     visitid AS visit, 
     channel AS channel, 
     conversionid AS conversionid 
     rn = ROW_NUMBER() OVER (PARTITION BY conversionid ORDER BY visit DESC) 
FROM db 
GROUP BY visitorid, 
     visitid, 
     channel, 
     conversionid) 

SELECT visitor, 
     MAX(visit) AS maxvisit, 
    channel, 
    conversionid 
FROM test 
WHERE rn = 1 
GROUP BY visitor, 
     channel 
ORDER BY visitor; 

这给了我最后点击归属。 (对于我来说,这样做有一个更简单的方法,但这种方式看起来并不灵活 - 我希望能够轻松地更改查询以排除渠道。)我的问题是,我该怎么做才能排除直接并将转化归因于最后一个非直接渠道?如果需要,我还希望能够排除其他渠道,以便我可以构建不同的归因模型。

感谢一百万人。

+0

什么,如果直接是用户的唯一渠道是否要排除该用户的所有在一起吗? – Matt

+0

加我看过你的代码和你的示例数据,并没有太多的区别。我可能会建议给我们一个例子,因为它更直接地与您的代码相关,然后向我们呈现您期望的输出。例如,MAX(visit)似乎无论通道如何都会获得Last VisitId。行号也是如此......所以你需要MAX(VisitId),然后MAX(VisitId)的Channel不是直接的,或者简单地MAX(VisitId,不是直接的)和该id的频道? – Matt

+0

有没有什么原因让你不要简单地添加“WHERE频道<>'直接'”? –

回答

0

这是有点不清楚你想要什么,所以这里有一些统计的例子,希望能让你更容易理解。本节面向条件聚合,它允许您进行混合和匹配,例如采取MAXVisitId,而不管相关联的conversion,并获得最后一个非直接的通道。

DECLARE @Table AS TABLE (visitor CHAR(1), VisitId INT, ConversionId INT, Channel VARCHAR(15)) 
INSERT INTO @Table VALUES ('a',1, 11,'email'),('a',2, 12,'email'),('a',3, 13,'direct') 
,('b',4, 14,'seo'),('b',5, 15,'direct'),('b',6, 16,'email'),('c',7, 17,'seo') 
,('c',8, 18,'direct'),('c',9, 19,'direct') 

    ;WITH cte AS (
     SELECT 
      visitor 
      ,VisitId 
      ,Channel 
      ,ConversionId 
      ,DirectConversion = CASE WHEN Channel = 'direct' THEN ConversionId END 
      ,ChannelRowNumber = ROW_NUMBER() OVER (PARTITION BY visitor 
       ORDER BY 
       CASE WHEN Channel = 'direct' THEN 1 ELSE 0 END 
       ,ConversionId DESC) 

     FROM 
      @Table 
    ) 

    SELECT 
     visitor 
     ,MaxVisitId = MAX(VisitId) 
     ,MaxVisitIdOfNonDirect = MAX(CASE WHEN DirectConversion IS NULL THEN VisitId END) 
     ,NumOfVisits = COUNT(DISTINCT VisitId) 
     ,Channel = MAX(CASE WHEN ChannelRowNumber = 1 THEN Channel END) 
     ,NumOfConversions = COUNT(DISTINCT ConversionId) 
     ,NumOfDirectConversions = COUNT(DISTINCT DirectConversion) 
     ,NumOfNonDirectConversions = COUNT(DISTINCT ConversionId) - COUNT(DISTINCT DirectConversion) 
    FROM 
     cte 
    GROUP BY 
     visitor 

如果你只是想排除频道一起,然后使用ROW_NUMBER和WHERE <>“直接”应该为你做的伎俩。

+0

哦,我认为这就是它!我需要更多的时间来验证,因为我今天在这里已经持续了很长时间,需要休息一下,但我认为你已经明确了它。 你能向我解释这是如何工作的吗?谷歌搜索“条件聚合”为我奠定了吗? – mowshowitz

+0

@mowshowitz是啊使用google搜索它可能会为你打好它,但想法是你在聚合函数内创建case表达式或iif,以便案例将有你不想计算,sum,max等的空值。所以当应用聚合时,它只是计算你想要的值。因此,在这种情况下,您可以过滤出直接值并仅汇总其他值。 – Matt

+1

精彩,非常感谢。 – mowshowitz

0

我认为有一个简单的方法:

SELECT db.* 
FROM (SELECT db.*, 
      ROW_NUMBER() OVER (PARTITION BY conversionid 
           ORDER BY (CASE WHEN channel <> 'Direct' THEN 1 ELSE 2 END), 
             visit DESC 
           ) as seqnum 
     FROM db 
    ) db 
WHERE seqnum = 1; 

这将返回最新记录每个conversionid不是Direct,如果有一个。

+0

看起来像恶意的多重匿名downvoting。 –

-1

在SQL Server下面的代码是值得尝试

select visitor,channel,conversionid, 
dense_rank() over(partition by visitor order by visit desc) as rn 
into #visitor 
from visitor 
where channel <> 'Direct' 
order by visitor,visit 

select v1.visitor,count(v2.visit) as visits ,v1.channel,v1.conversionid 
from #visitor v1 join visitor v2 
on v1.visitor=v2.visitor and v1.rn=1 
group by v1.visitor,v1.channel,v1.conversionid 
相关问题