【问题标题】:Retrieve records against most recent state/attribute value根据最近的状态/属性值检索记录
【发布时间】:2016-01-13 04:01:27
【问题描述】:

在 Redshift 中使用非规范化结构并计划是继续创建记录,同时检索仅考虑针对用户的最新属性。

以下是表格:

user_id   state  created_at
1         A      15-10-2015 02:00:00 AM
2         A      15-10-2015 02:00:01 AM
3         A      15-10-2015 02:00:02 AM
1         B      15-10-2015 02:00:03 AM
4         A      15-10-2015 02:00:04 AM
5         B      15-10-2015 02:00:05 AM

所需的结果集是:

user_id   state  created_at
2         A      15-10-2015 02:00:01 AM
3         A      15-10-2015 02:00:02 AM
4         A      15-10-2015 02:00:04 AM

我有检索上述结果的查询:

select user_id, first_value AS state
from (
   select user_id, first_value(state) OVER (
                     PARTITION BY user_id
                     ORDER BY created_at desc
                     ROWS between UNBOUNDED PRECEDING and CURRENT ROW)
   from customer_properties
   order by created_at) t
where first_value = 'A'

这是检索的最佳方式还是可以改进查询?

【问题讨论】:

  • created_at 列正在查询中使用,但在示例数据中缺失,问题已更新。

标签: sql postgresql greatest-n-per-group amazon-redshift


【解决方案1】:

最佳查询取决于各种细节:查询谓词的选择性、基数、数据分布。如果state = 'A' 是一个选择性条件(查看符合条件的行),那么这个查询应该会快很多:

SELECT c.user_id, c.state
FROM   customer_properties c
LEFT   JOIN customer_properties c1 ON c1.user_id = c.user_id
                                  AND c1.created_at > c.created_at
WHERE  c.state = 'A'
AND    c1.user_id IS NULL;

提供(state)(甚至(state, user_id, created_at))上有一个索引,(user_id, created_at) 上有另一个索引。

有多种方法可以确保不存在更高版本的行:

如果'A'state 中的常用值,则这个更通用的查询会更快:

SELECT user_id, state
FROM (
   SELECT user_id, state
        , row_number() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn
   FROM   customer_properties
   ) t
WHERE  t.rn = 1
AND    t.state = 'A';

我删除了NULLS LAST,假设created_at 定义为NOT NULL。另外,我认为 Redshift 没有:

这两个查询都应该适用于 Redshift 的有限功能。使用现代 Postgres,有更好的选择:

如果最新的行匹配,您的原始文件将根据user_id 返回所有 行。你将不得不折叠重复,不必要的工作......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 2022-01-01
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    相关资源
    最近更新 更多