Как я могу использовать функцию SUM с предложением OVER, имеющим те же значения в порядке столбца, чтобы вернуть правильную сумму? - PullRequest
0 голосов
/ 27 июня 2019

У меня есть сценарий, в котором мне нужно получить столбец суммы с помощью функции sql 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 ]

1 голос
/ 27 июня 2019

По умолчанию в 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;
0 голосов
/ 27 июня 2019

Я попытаюсь объяснить, используя стандартный SQL.Вы пытаетесь сгруппировать dateCol, myCol с функцией суммирования.По сути, вам нужно определить предложение GROUP BY, а представление результатов можно отсортировать, используя обычный порядок по выражению

  select dateCol, myCol,
         sum(case when dateCol is not null  then 1 else 0 end)  as sumCol
  from sampleTable
  group by dateCol, myCol
  order by dateCol
...