【问题标题】:Count Visits by Source for 30 Day Prior Period for each Purchase按来源统计每次购买前 30 天的访问次数
【发布时间】:2020-09-04 18:24:05
【问题描述】:

我有一个记录网站活动的表格,其中包含以下列和数据

ID  Date         Source  Revenue

1   2013-10-01   A       0
2   2013-10-01   A       0
3   2013-10-01   B       10
1   2013-10-02   A       40
4   2013-10-03   B       0
3   2013-10-03   B       0
4   2013-10-04   A       10

我正在尝试创建一个表格,该表格包含每笔交易(收入 > 0),并按来源计算过去 30 天内各个列中的所有访问次数。它应该看起来像这样。

ID  Date         Source  Revenue Count_A  Count_B

3   2013-10-01   B       10      0        1
1   2013-10-02   A       40      2        0
4   2013-10-04   A       10      1        1

我已尝试对这些列中的每一列使用子查询,但计数太差了,我不知道为什么。

Select ID,
       Date,
       Source,
       Revenue,
       (SELECT Count(*) 
               FROM table t2
               WHERE t2.Date between t.Date-30 and t.Date and Source = 'A') AS Count_A
       (SELECT Count(*) 
               FROM table t3
               WHERE t3.Date between t.Date-30 and t.Date and Source = 'B') AS Count_B
  FROM table t
  Where Revenue > 0
  Order By WMEID

我正在使用 Microsoft SQL Server。

【问题讨论】:

  • 如何Source - A 约会2013-10-02 Count_A=2
  • 因为客户“1”在通过来源 A 进行购买前 30 天内访问了该网站两次。一次在“2013-10-01”他们没有购买,一次在“ 2013-10-02”他们在哪里。目标是计算客户在购买前 30 天访问网站的次数以及他们通过哪些渠道访问网站。

标签: sql sql-server tsql count e-commerce


【解决方案1】:

使用横向连接:

Select l.*, l2.*
from logs l outer apply
     (select sum(case when l2.source = 'A' then 1 else 0 end) as count_a,
             sum(case when l2.source = 'B' then 1 else 0 end) as count_b
      from logs l2
      where l2.id = l.id and
            l2.date >= dateadd(day, -30, l.date) and
            l2.date <= l.date
     ) l2
where l.Revenue > 0
order By l.WMEID;

我认为您的方法的问题在于您与 id 不匹配。

【讨论】:

    【解决方案2】:

    您的计数已关闭,因为您的子选择与外部查询不相关,因此总数与行中的其他数据无关。此外,子选择中没有GROUP BY,因此您将获得总表数。而且我不太确定那个日期逻辑。

    可以通过将相关性添加到每个子选择 (WHERE...t2.ID = t.ID AND t2.Date = t.Date, etc) 并为每个查询添加适当的 GROUP BY 子句来纠正所有这些问题。但这是相当多的打字,难以维护,难以阅读。它还可能会生成多个表扫描,因此可能会成为性能问题。

    相反,我会选择条件聚合:

    Select t.ID,
           t.Date,
           t.Source,
           SUM(t.Revenue) AS Revenue,
           SUM(CASE WHEN t.Source = 'A' THEN 1 ELSE 0 END) AS Count_A,
           SUM(CASE WHEN t.Source = 'B' THEN 1 ELSE 0 END) AS Count_B
      FROM mytable t
      Where Revenue > 0
        AND t.Date >= DATEADD(DAY, -30, CAST(GETDATE() AS date))
        AND t.Date < CAST(GETDATE() AS date)
      GROUP BY 
           t.ID,
           t.Date,
           t.Source
      Order By t.Date
    

    结果(基于问题中的结构,而不是数据):

    +----+------------+--------+---------+---------+---------+
    | ID |    Date    | Source | Revenue | Count_A | Count_B |
    +----+------------+--------+---------+---------+---------+
    |  3 | 2020-05-01 | B      |      60 |       0 |       2 |
    |  1 | 2020-05-02 | A      |      40 |       1 |       0 |
    |  4 | 2020-05-04 | A      |      10 |       1 |       0 |
    +----+------------+--------+---------+---------+---------+
    

    这是SQL Fiddle

    【讨论】:

    • 感谢您的帮助!一旦我将 Date 和 Sum 组件转换到真实数据上,某些东西仍然无法使用。我会看看这是否是我的格式问题,或者我是否把问题表述错了,然后跟进。
    猜你喜欢
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多