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

Count number of events before and after a particular event in SQL?

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

我尝试了很多查询,但都没有用。任何想法,如何解决这个问题?

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

希望这能回答您的问题

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'

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

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

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

以下适用于 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'