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