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

时间:2018-02-13 15:53:44

标签: sql google-bigquery legacy-sql

我有一张包含日期和事件的表格。有一个名为'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

我尝试了很多查询,但它无效。任何想法,如何解决这个问题?

4 个答案:

答案 0 :(得分:1)

下面是BigQuery Standard 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'  

答案 1 :(得分:0)

对于每个“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”,我不确定使用了什么逻辑。

答案 2 :(得分:0)

希望这能回答你的问题

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'

答案 3 :(得分:0)

如果要计算在事件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