如何将SUM函数与具有相同值的OVER子句按列使用以返回正确的总和?

时间:2019-06-27 15:05:32

标签: sql postgresql sql-order-by window-functions

我有一种情况,我需要使用sql SUM函数获取sum列。我有一个像这样的示例数据:


sampleTable:

      dateCol,  myCol
    ('12:00:01',3),
    ('12:00:01',4),
    ('12:00:01',5),
    ('12:00:01',NULL),
    ('12:00:01',NULL), 
    ('12:00:01',3)

我正在使用下面的查询来获取myCol列的总和

select dateCol, myCol,
             sum(case when dateCol is not null  then 1 end) over (order by dateCol) as sumCol
      from   sampleTable;

我得到以下结果:

    dateCol myCol   sumCol
1   12:00:01    3       4
2   12:00:01    4       4
3   12:00:01    5       4
4   12:00:01    NULL    4
5   12:00:01    NULL    4
6   12:00:01    3       4

但是我希望结果是:

    dateCol myCol   sumCol
1   12:00:01    3       1
2   12:00:01    4       2
3   12:00:01    5       3
4   12:00:01    NULL    3
5   12:00:01    NULL    3
6   12:00:01    3       4

如何修改查询以获得预期结果?

2 个答案:

答案 0 :(得分:1)

SQL中累积总和的默认值为RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,而不是ROWS BETWEEN UNBOUNDED PRECEDING。您似乎无法区分行。

您可以尝试使用明确的窗口规范:

select dateCol, myCol,
       count(dateCol) over (order by dateCol rows between unbounded preceding and current row) as sumCol
from sampleTable;

请注意,我也使用count()而不是sum()简化了逻辑。

如果您有一列要指定顺序,请在order by中使用该列:

select dateCol, myCol,
       count(dateCol) over (order by dateCol, ?) as sumCol
from sampleTable;

这将使排序稳定并区分行。

如果没有,您可以创建一列。但是,结果的顺序可能不同-SQL表表示无序集。所以:

select dateCol, myCol,
       count(dateCol) over (order by dateCol, seqnum) as sumCol
from (select st.*, row_number() over (order by dateCol) as seqnum
      from sampleTable
     ) st;

答案 1 :(得分:0)

我将尝试解释使用标准SQL。您正在尝试将dateCol,myCol与聚合函数总和分组。基本上,您需要定义GROUP BY子句,并且可以使用普通的order by子句对结果视图进行排序

createNode