【问题标题】:How to count number of a particular event before another event in SQL Bigquery?如何在 SQL Bigquery 中的另一个事件之前计算特定事件的数量?
【发布时间】:2018-02-14 19:23:53
【问题描述】:

我有一个包含日期、事件和用户的表格。有一个名为“A”的事件。我想找出特定事件在 Sql Bigquery 中事件“A”之前和之后发生了多少次。例如,

   User           Date             Events
    123          2018-02-13            X.Y.A
    123          2018-02-12            X.Y.B
    134          2018-02-10            Y.Z.A
    123          2018-02-11            A
    123          2018-02-01            X.Y.Z
    134          2018-02-05            X.Y.B
    134          2018-02-04            A

输出会是这样的

User       Event    Before   After
123          A      1        3
134          A      0        1

我必须计算的事件包含一个特定的前缀。意味着我必须检查以( X.Y.then 一些事件名称)开头的事件。所以,X.Y.SomeEvent 是我必须设置计数器的事件。有什么建议吗?

【问题讨论】:

    标签: sql google-bigquery legacy-sql


    【解决方案1】:

    以下是 BigQuery SQL

    #standardSQL
    SELECT user, event, before, after 
    FROM (
      SELECT user, event, 
        COUNTIF(event LIKE 'X.Y.%') OVER(PARTITION BY user ORDER BY dt ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) before,
        COUNTIF(event LIKE 'X.Y.%') OVER(PARTITION BY user ORDER BY dt ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ) after
      FROM `project.dataset.events`
    )
    WHERE event = 'A'
    -- ORDER BY user
    

    您可以在问题中使用虚拟数据对其进行测试

    #standardSQL
    WITH `project.dataset.events` AS (
      SELECT 123 user, '2018-02-13' dt, 'X.Y.A' event UNION ALL
      SELECT 123, '2018-02-12', 'X.Y.B' UNION ALL
      SELECT 123, '2018-02-11', 'A' UNION ALL
      SELECT 134, '2018-02-10', 'Y.Z.A' UNION ALL
      SELECT 134, '2018-02-05', 'X.Y.B' UNION ALL
      SELECT 134, '2018-02-04', 'A' UNION ALL
      SELECT 123, '2018-02-01', 'X.Y.Z' 
    )
    SELECT user, event, before, after 
    FROM (
      SELECT user, event, 
        COUNTIF(event LIKE 'X.Y.%') OVER(PARTITION BY user ORDER BY dt ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) before,
        COUNTIF(event LIKE 'X.Y.%') OVER(PARTITION BY user ORDER BY dt ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ) after
      FROM `project.dataset.events`
    )
    WHERE event = 'A'
    ORDER BY user
    

    【讨论】:

    • 嘿米哈伊尔,谢谢它对我有用。我只是想知道一件事。这里我们假设 A 只出现一次。如果事件 A 对一个用户发生多次怎么办?我们如何确保同一事件“X.Y”不计入另一个 A?
    • 在您之前的问题中,您说Each user has Event A only once 因此上述解决方案利用了这一事实。
    • 是的,但我正在努力学习这一点,并且很想知道如何实现这一点。
    • 明白。我建议您发布您的新问题,这样我们就不受 cmets 格式的限制:o)
    【解决方案2】:

    用户窗口函数用于查找“A”出现的日期。然后使用条件聚合来统计前后的事件:

    select userid,
           sum(case when date < a_date and event like 'X.Y%' then 1 else 0 end) as before,
           sum(case when date > a_date and event like 'X.Y%' then 1 else 0 end) as before
    from (select t.*,
                 min(case when event = 'A' then date end) over (partition by userid) as a_date
          from t
         ) t
    group by userid
    

    【讨论】:

    • 嘿 Gordon,我在运行查询时遇到此错误。你能告诉我我做错了什么吗?错误:SELECT 子句混合了聚合 'a_date' 和字段 'user、name、EventDate' 而没有 GROUP BY 子句
    猜你喜欢
    • 1970-01-01
    • 2020-04-16
    • 2022-08-21
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    相关资源
    最近更新 更多