计算SQL中特定事件之前和之后的事件数?

Posted

技术标签:

【中文标题】计算SQL中特定事件之前和之后的事件数?【英文标题】:Count number of events before and after a particular event in SQL? 【发布时间】:2018-02-13 15:53:43 【问题描述】:

我有一个包含日期和事件的表格。有一个名为“A”的事件。我想知道在 Sql Bigquery 中事件“A”之前和之后发生了多少事件。 例如,

User           Date             Events
123          2018-02-13            D
123          2018-02-12            B
123          2018-02-10            C
123          2018-02-11            A
123          2018-02-01            X

答案是这样的。

  User       Event    Before   After
  123          A       2        2

我已经尝试了很多查询,但都不起作用。任何想法,如何解决这个问题?

【问题讨论】:

当然 :o) - 这个例子是不是过于简单了,或者你真的只有一个事件 A 在那个表中?我认为在您最初的问题中,我看到两行带有 A 实际上,它来自我有多个用户的表。每个用户只有一次事件 A,但其他事件重复多次。我为单个用户分离了数据。这样我想如果问题解决了,我可以为整个表实现它。实际的答案是:userid event(i.e A) before value after value. 【参考方案1】:

以下是 BigQuery 标准 SQL

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

【讨论】:

在这个答案中,我必须手动合并所有可能的事件。这对于大表来说很难实现。 什么意思?这是你的问题吗? :o) 只需删除WHERE event = 'A',您就可以在所有用户的每个事件之前和之后获得!试着让我知道 嘿米哈伊尔,如果我必须更改查询以检查特定事件在 A 之前发生了多少次。但问题是我必须检查的事件包含特定前缀。意味着我必须检查以( X.Y.then 一些事件名称)开头的事件。所以,X.Y.SomeEvent 是我必须设置计数器的事件。有什么想法吗? 我认为,您应该将此作为一个新问题发布,这样我们就不受 cmets 格式的限制【参考方案2】:

对于每个“A”,您可以使用row_number()lead() 获取到下一个“A”的事件数:

select t.*,
       (lead(seqnum) over (order by date) - seqnum - 1) as num_other_events
from (select t.*, row_number() over (order by date) as seqnum
      from t
     ) t
where event = 'A';

这会为每个“A”生成结果。鉴于您的示例数据中有三个“A”并且只想要“2”,我不确定用于此的逻辑是什么。

【讨论】:

【参考方案3】:

如果您想在事件 A 的行之前计算出现在表中的事件数,则无法执行此操作,因为 BigQuery 不会保留表中行的物理顺序。

如果你想使用日期列计算之前和之后,你可以这样做

WITH
  events AS (
  SELECT
    DATE('2018-02-13') AS event_date,
    "D" AS event
  UNION ALL
  SELECT
    DATE('2018-02-12') AS event_date,
    "B" AS event
  UNION ALL
  SELECT
    DATE('2018-02-10') AS event_date,
    "C" AS event
  UNION ALL
  SELECT
    DATE('2018-02-11') AS event_date,
    "A" AS event
  UNION ALL
  SELECT
    DATE('2018-02-01') AS event_date,
    "X" AS event),
  event_a AS (
  SELECT
    *
  FROM
    events
  WHERE
    event = "A")
SELECT
  ANY_VALUE(event_a.event) AS Event,
  COUNTIF(events.event_date<event_a.event_date) AS Before,
  COUNTIF(events.event_date>event_a.event_date) AS After
FROM
  events,
  event_a

【讨论】:

【参考方案4】:

希望这能回答你的问题

Create table #temp(T_date varchar(100),Events varchar(100))

insert into #temp values
('2018-02-13','A'),
('2018-02-12','B'),
('2018-02-10','C'),
('2018-02-11','A'),
('2018-02-01','X'),
('2018-02-06','A')

select max(rn)-min(rn)
from
(
select *,ROW_NUMBER() over(order by (select 1)) as rn from #temp
)a
where Events='A'

【讨论】:

以上是关于计算SQL中特定事件之前和之后的事件数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Bigquery 中的另一个事件之前计算特定事件的数量?

如何编写 pyspark map-reduce 来计算日期之前的事件数

vue变量替换为特定值之后总是变成之前的值

给定具有开始和结束时间的事件,如何使用 Spark 计算同时发生的事件数?

利用SQL Profiler 追踪数据库操作

CE 更新事件:有啥方法可以将之前/之后的属性值传递给工作流?