Google bigquery 窗口中的过滤分区——BigQuery中的事件最近度计算

Google bigquery 窗口中的过滤分区——BigQuery中的事件最近度计算,google-bigquery,Google Bigquery,有没有什么方法可以模拟标准SQLBigQuery中FILTER()的行为 我需要做的是: 选择 最大(日期)筛选器(其中事件_happend=1) 结束( 按用户id划分 按日期订购ASC 无界前置和1前置之间的行 ) 从…起 ... 本质上,我需要计算出在当前行的日期之前某个事件发生的最近日期。 列事件发生获取值0和1,我需要当前行日期之前事件发生的最新日期(事件发生=1) 有什么方法可以模仿过滤器的行为吗 试试这个: #standardSQL WITH SampleData AS (

有没有什么方法可以模拟标准SQLBigQuery中FILTER()的行为

我需要做的是:

选择
最大(日期)筛选器(其中事件_happend=1)
结束(
按用户id划分
按日期订购ASC
无界前置和1前置之间的行
)
从…起
...

本质上,我需要计算出在当前行的日期之前某个事件发生的最近日期。 列
事件发生
获取值
0
1
,我需要当前行日期之前事件发生的最新日期(
事件发生=1

有什么方法可以模仿过滤器的行为吗

试试这个:

#standardSQL
WITH SampleData AS (
  SELECT 1 AS user_id, DATE '2017-11-02' AS date, 1 AS event_happend UNION ALL
  SELECT 1, DATE '2017-11-03', 0 UNION ALL
  SELECT 1, DATE '2017-11-04', 1 UNION ALL
  SELECT 1, DATE '2017-11-04', 1 UNION ALL
  SELECT 1, DATE '2017-11-05', 0 UNION ALL
  SELECT 2, DATE '2017-11-10', 1 UNION ALL
  SELECT 2, DATE '2017-11-11', 0 UNION ALL
  SELECT 2, DATE '2017-11-20', 0 UNION ALL
  SELECT 2, DATE '2017-11-21', 1
)
SELECT
  user_id,
  date,
  MAX(IF(event_happend = 1, date, NULL)) OVER (
    PARTITION BY user_id ORDER BY UNIX_DATE(date)
    RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
  ) AS max_date
FROM SampleData;

我加入了
user\u id
date
来查看发生了什么。请注意,在这里使用
范围
很重要——如果使用
,则窗口中的前一行可能具有相同的
日期
值。通过将
RANGE
与前面的
1一起使用
,您可以强制窗口中的所有行的
date
值小于当前值。

Mikhail Berlyant提供的解决方案对于所问问题非常有效。我遇到了一个稍微不同的问题,即聚合的列与
OVER
子句中的
orderby
语句不同。我需要的聚合函数是
First\u value
,但只要您可以指定
ignorenulls
,它就可以与其他函数一起工作。例如:

ColumnToBeFiltered | Value      | PartitionColumn | OrderingColumn
FOO                | APPLE      | A               | 1
BAR                | BANANA     | A               | 2
FOO                | ORANGE     | A               | 3
FOO                | CHERRY     | B               | 8
BAR                | MANGO      | B               | 10
BAR                | POMELO     | B               | 9
对于每个分区,如果您想在过滤列为“BAR”时基于OrderingColumn获取第一个
,我是这样解决的:

FIRST_VALUE(IF (columnToBeFiltered = 'BAR', Value, null) IGNORE NULLS) 
OVER (PARTITION BY PartitionColumn ORDER BY OrderingColumn)
AS FirstFilteredValue
对于分区
A的每一行,它将返回
Banana
;对于分区
B的每一行,它将返回
pomero

ColumnToBeFiltered | Value    | PartitionColumn | OrderingColumn | FirstFilteredValue
FOO                | APPLE    | A               | 1              | BANANA
BAR                | BANANA   | A               | 2              | BANANA
FOO                | ORANGE   | A               | 3              | BANANA
FOO                | CHERRY   | B               | 8              | POMELO
BAR                | MANGO    | B               | 10             | POMELO
BAR                | POMELO   | B               | 9              | POMELO

我希望它能帮助其他人。

为什么不使用范围而不是行?然后您可以排除当前行的值。@ElliottBrossard感谢您的建议-但是我不太明白使用范围对我有什么帮助。你能详细说明一下吗?我还向我的问题中添加了以下内容以进行澄清:“列event_occurrent的值为0和1,我需要事件发生的最新日期event_occurrent=当前行日期之前的1。”@ElliottBrossard我还更新了我问题中日期列的名称-我最初的选择有点混淆如果窗口中有多个相同的
date
值,这可能会给出错误的答案-请参阅我的解决方案,其中包含
范围
:o)
MAX(如果(event_happend=1,date,null))
是关于
过滤器的答案的核心-我没有修改原始问题的任何其他内容,因为OP所期望的确切逻辑并不明确。我同意,但OP确实声明“在当前行的日期之前”,因此,考虑到这一点似乎很重要。我认为我的重点是
是否有任何方法可以模拟过滤器的行为?
我已经编辑了我的答案,以使其清晰。抱歉,伙计们,我应该澄清,FROM语句中的表已经是每日聚合的数据,因此在我的情况下行足够了,但范围可能很小更一般地纠正。无论如何,
MAX(如果(event_happend=1,date,NULL))
语句正是我想要的,我非常感谢你们提供了这一点。我希望我能接受这两个答案,所以我会接受第一个答案。
ColumnToBeFiltered | Value    | PartitionColumn | OrderingColumn | FirstFilteredValue
FOO                | APPLE    | A               | 1              | BANANA
BAR                | BANANA   | A               | 2              | BANANA
FOO                | ORANGE   | A               | 3              | BANANA
FOO                | CHERRY   | B               | 8              | POMELO
BAR                | MANGO    | B               | 10             | POMELO
BAR                | POMELO   | B               | 9              | POMELO