计算独特的组合直到日期 - 每月

时间:2018-05-16 20:21:32

标签: sql postgresql

我正在查看一个包含双面平台交易数据的表格,您可以在这里找到买家和卖家。我想知道买家和卖家的独特组合的总量。让我们说,安倍在1月份从布兰登那里购买了1个组合。如果安倍在2月份购买Cece,那就是2,但如果安倍再次从布兰登购买,它仍然是2。

我的解决方案是使用DENSE_RANK()函数:

WITH
combos AS (
  SELECT
        t.buyerid, t.sellerid,
        DENSE_RANK() OVER (ORDER BY t.buyerid, t.sellerid) AS combinations

    FROM transactions t

    WHERE t.transaction_date < '2018-05-01'
)
SELECT
    MAX(combinations) AS total_combinations

FROM combos

这很好用。每个新组合获得更高的排名,如果您选择该结果的MAX,您就知道唯一组合的数量。

但是,我想知道每月独特组合的总量。这里的问题是,如果我按事务月份进行分组,则仅计算该月份的唯一组合。在Abe的例子中,它将在1月份成为一个独特的组合,然后是下个月的另一个组合,因为它是如何在SQL中进行分组的。

示例:

transaction_date  buyerid  sellerid
2018-01-03        3828     219
2018-01-08        2831     123
2018-02-10        3828     219

所有这些行的DENSE_RANK()命名组合的输出是:

transaction_date  buyerid  sellerid  combinations
2018-01-03        3828     219       1
2018-01-08        2831     123       2
2018-02-10        3828     219       2

因此,在选择MAX组合时,您知道独特的买方/卖方组合的数量,这是在这里。

但是,我希望在每个月的开始之前看到一直运行的独特组合,直到现在为止所有月份。但是,当我们按月分组时,它会是这样的:

transaction_date  buyerid  sellerid  month combinations
2018-01-03        3828     219       jan   1
2018-01-08        2831     123       jan   2
2018-02-10        3828     219       feb   1

虽然我实际上想要输出如下:

month  total_combinations_at_month_start
jan    0
feb    2
mar    2

我该如何解决这个问题?我试图在各种窗口功能上寻求帮助,但直到现在还没有运气。谢谢!

1 个答案:

答案 0 :(得分:0)

这是一种方法:

WITH combos AS (
      SELECT t.*,
             ROW_NUMBER() OVER (PARTITION BY sellerid, buyerid ORDER BY t.transaction_date) as combo_seqnum,
             ROW_NUMBER() OVER (PARTITION BY sellerid, buyerid, date_trunc('month', t.transaction_date) ORDER BY t.transaction_date) as combo_month_seqnum
      FROM transactions t

      WHERE t.transaction_date < '2018-05-01'
    )
SELECT 'Overall' as which, COUNT(*)
FROM combos
WHERE combo_seqnum = 1
UNION ALL
SELECT to_char(transaction_date, 'YYYY-MM'), COUNT(*)
FROM combos
WHERE combo_month_seqnum = 1
GROUP BY to_char(transaction_date, 'YYYY-MM');

这会将结果放在单独的行中。如果您想要每月的累积数量和数量:

SELECT to_char(transaction_date, 'YYYY-MM'),
       SUM( (combo_month_seqnum = 1)::int ) as uniques_in_month,
       SUM(SUM( (combo_seqnum = 1)::int )) OVER (ORDER BY to_char(transaction_date, 'YYYY-MM')) as uniques_through_month
FROM combos
GROUP BY to_char(transaction_date, 'YYYY-MM')

Here是一个说明解决方案的rextester。