对不起,标题含糊。不确定如何命名。
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
我的方法看似不正确,但确实可以。我如何做得更好?
答案 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