BigQuery:按每个用户的最后日期选择值

时间:2019-12-10 14:46:25

标签: sql google-bigquery greatest-n-per-group

对不起,标题含糊。不确定如何命名。

user_id  | transaction_amount | date  
1        | 100                | 2019-12-15
1        | 250                | 2019-12-16 
2        | 300                | 2019-12-11
2        | 415                | 2019-12-12

我需要为每个用户选择最新的transaction_amount:

user_id  | transaction_amount | date  
1        | 250                | 2019-12-16 
2        | 415                | 2019-12-12

我该怎么做?

这是我现在要做的:

SELECT
  user_id,
  transaction_amount
FROM the_original_table VT1
  WHERE date = (
    SELECT
      MAX(date)
    FROM the_original_table VT2
    WHERE
      VT1.user_id = VT2.user_id
  )
GROUP BY
  user_id,
  date,
  transaction_amount

我的方法看似不正确,但确实可以。我如何做得更好?

4 个答案:

答案 0 :(得分:1)

使用相关子查询进行过滤是一种很好的方法。您可以删除group by子句,因为它实际上没有意义:因为它适用于所有列,所以它没有任何用处(除了删除可能的重复项,在这里似乎没有发生):

select t.*
from the_original_table t
where t.date = (
    select max(t1.date) from the_original_table t1 where t1.user_id = t.user_id
)

为了提高性能,您希望在(user_id, date)上建立索引。

答案 1 :(得分:1)

使用具有row_number而不是array_agg的cte,更容易阅读大多数供应商支持的内容:

with ctetbl as (
   select user_id, transaction_amount, date
         ,row_number() over (partition by user_id order by date desc) as rn
   from the_original_table
)
select user_id, transaction_amount, date
from ctetbl
where rn = 1

答案 2 :(得分:0)

在BigQuery中,我只使用聚合:

select array_agg(t order by date desc limit 1).*
from the_original_table  t
group by user_id

答案 3 :(得分:0)

以下内容适用于BigQuery标准SQL和非常类似于BigQuery的风格

#standardSQL
SELECT AS VALUE ARRAY_AGG(t ORDER BY `date` DESC LIMIT 1)[OFFSET(0)]
FROM `project.dataset.the_original_table` t
GROUP BY user_id     

如果要应用到您的问题的示例数据中,如以下示例所示

#standardSQL
WITH `project.dataset.the_original_table` AS (
  SELECT 1 user_id, 100 transaction_amount, '2019-12-15' `date` UNION ALL
  SELECT 1, 250, '2019-12-16' UNION ALL 
  SELECT 2, 300, '2019-12-11' UNION ALL
  SELECT 2, 415, '2019-12-12' 
)
SELECT AS VALUE ARRAY_AGG(t ORDER BY `date` DESC LIMIT 1)[OFFSET(0)]
FROM `project.dataset.the_original_table` t
GROUP BY user_id     

结果是

Row user_id transaction_amount  date     
1   1       250                 2019-12-16   
2   2       415                 2019-12-12