【问题标题】:SUM distinct inside window functionSUM distinct 内窗函数
【发布时间】:2021-11-13 18:49:26
【问题描述】:

我有一个类似这样的数据结构:

CREATE TABLE some_table (
    dude_id INTEGER, 
    main_date TIMESTAMP, 
    how_many INTEGER, 
    how_much NUMERIC(5,2), 
    their_ids INTEGER[]
)

这是我目前得到的查询

SELECT
    dude_id,
    main_date,
    how_many,
    how_much,
    their_ids,
    SUM(how_many) OVER (PARTITION BY dude_id ORDER BY main_date) AS count_stuff_WRONG,
    SUM(how_much) OVER (PARTITION BY dude_id ORDER BY main_date) AS cumulative_sum_WRONG
FROM some_table

这是我想要达到的结果:

dude_id main_date how_many how_much their_ids count_stuff_EXPECTED cumulative_sum_EXPECTED count_stuff_WRONG cumulative_sum_WRONG
38 2019-06-14 1 6 373 1 6 1 6
38 2019-07-15 1 7 374 2 13 (6+7) 2 13 (6+7)
38 2019-07-16 1 8 375 3 21 (6+7+8) 3 21 (6+7+8)
38 2020-06-14 1 16 373 3 31 (7+8+16) 4 37 (6+7+8+16)
38 2020-07-15 1 17 374 3 41 (8+16+17) 5 54 (6+7+8+16+17)
38 2020-07-16 1 18 375 3 51 (16+17+18) 6 72 (6+7+8+16+17+18)

count_stuff_EXPECTEDcumulative_sum_EXPECTED 列是我想要得到的,count_stuff_WRONGcumulative_sum_WRONG 列是我当前查询返回的。

换句话说,我想获得每个 main_date 的累积值,但不计算/求和多次相同的their_ids。所以以第 4 行为例,窗口分区有不止一次的their_ids {373},所以它应该只考虑最近的一个(第 4 行)而不考虑第一次出现(第 1 行)

注意:无需在查询中显示总和是如何计算的,为了清楚起见,我只是将其放在括号中。

我尝试过使用

SUM(DISTINCT how_many) over (PARTITION BY dude_id ORDER BY main_date) as count_stuff

但是得到了

错误:没有为窗口函数实现 DISTINCT

SQL 小提琴:http://sqlfiddle.com/#!17/44850/2

【问题讨论】:

    标签: postgresql aggregate-functions distinct window-functions


    【解决方案1】:

    也许这不是最好的答案,但我认为它可以达到你的目标。

    首先,我自己创建一个表数据的INNER JOIN,以获得每行的总和(每个 their_ids 的更新记录)。然后我GROUP BY 丢弃“重复”的行,我终于得到了总和。

    WITH sq1 AS (SELECT d1.dude_id, d1.main_date, d1.how_many, d1.how_much, d1.their_ids,
                        d2.dude_id AS d2_dude_id, d2.main_date AS d2_main_date, d2.their_ids AS d2_their_ids,
                       FIRST_VALUE(d2.how_much) OVER (PARTITION BY d1.dude_id, d1.main_date, d1.their_ids, d2.their_ids ORDER BY d2.main_date DESC) AS how_much_to_sum
                 FROM data d1
                 INNER JOIN data d2 ON d1.dude_id = d2.dude_id AND d1.main_date >= d2.main_date),
                
         sq2 AS (SELECT dude_id, main_date, how_many, how_much, their_ids, d2_dude_id, d2_their_ids, MIN(how_much_to_sum) AS how_much_to_sum
                 FROM sq1
                 GROUP BY dude_id, main_date, how_many, how_much, their_ids, d2_dude_id, d2_their_ids)
                 
    select
          dude_id,
          main_date,
          how_many,
          how_much,
          their_ids,
          SUM(how_many) AS count_stuff,
          SUM(how_much_to_sum) AS cumulative_sum
          
    from sq2
    GROUP BY dude_id, main_date, how_many, how_much, their_ids
    ORDER BY main_date;
    

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      相关资源
      最近更新 更多