PostgreSQL 中超过一年窗口的模式

Posted

技术标签:

【中文标题】PostgreSQL 中超过一年窗口的模式【英文标题】:Mode over a one year window in PostgreSQL 【发布时间】:2017-03-14 17:44:39 【问题描述】:

我有一个来自成员的事务的 Redshift 表,并且与每个事务相关联的是一个状态:

      date|member_id|transaction_amount|state
----------+---------+------------------+-----
01/05/2012|aaaaaaaaa|             35.50|   WA
02/05/2012|aaaaaaaaa|             35.50|   WA
03/05/2012|aaaaaaaaa|             35.50|   WA
                     ...
01/05/2013|aaaaaaaaa|             35.50|   WA
02/05/2013|aaaaaaaaa|             35.50|   CA
03/05/2013|aaaaaaaaa|             35.50|   CA
                     ...

我想做的是,对于每笔交易,选择过去 12 个月中发生最多的状态,并将其与给定交易相关联。

我的第一个想法是像这样进行连接:

select t0.*, t1.state from transactions t0
join transactions t1
on datediff('month', t1.date, t0.date) between 0 and 12

然后我将按datemember_id、其他未显示的列、transaction_amount 分组,并计算每个状态的出现次数,保留出现最多的状态(在该组中具有最大的 count) .

我在做最后一部分时遇到了麻烦。我的问题是,如何从该表中为每个组选择最频繁的状态?另一个问题是,有没有更有效的方法来做到这一点(避免这种加入)?

【问题讨论】:

【参考方案1】:

运行模式真的很棘手。您可以通过以下方式修改您的查询:

select id, state
from (select t.id, t2.state, count(*) as cnt,
             row_number() over (partition by t.id order by count(*) desc) as seqnum
      from transactions t join
           transactions t2
           on datediff('month', t2.date, t.date) between 0 and 12
      group by t1.id, t2.state
     ) ts
where seqnum = 1;

这只是使用交易ID。您可能想要测试这个版本,您可以在其中重新加入以获取您想要的字段,以及您在此查询中包含字段的第二个版本。

(您可能还想包括member_id;在这一点上问题还不清楚。)

如果没有自联接(或等效项),我很难想出在 Redshift 中执行此操作的方法。

【讨论】:

以上是关于PostgreSQL 中超过一年窗口的模式的主要内容,如果未能解决你的问题,请参考以下文章

PostgresQL 中超出堆栈深度限制(删除触发器后)

Postgresql 学习记录,模式,分区表,触发器,事务,窗口函数,视图,建表,约束等

为啥运行我的 js resizer 代码会使文档在 IE7 - IE11 和 MS Edge 中超过 100% 的窗口高度和宽度?

如何将 POST 连接到通过 AJAX 加载的不同剃须刀页面到模式弹出窗口中?

如何在 PostgreSQL 中选择某一年之后的日期

如何在postgresql中使用CASE和Between in where条件一年