почему запрос приводит к среднему значению для окна вместо текущей суммы?
Это не среднее значение для окна.В вашей версии rownum
показаны четыре значения: 6270, 6540, 6630 и 7080, что в среднем составляет 6630.
Это текущая сумма, но, возможно, не совсем то, что вы ожидали, и порядоквывод, который отображается, скрывает логику, которую вы на самом деле применяете.
Вы можете увидеть, откуда приходят цифры, которые вы видите, упорядочив вывод:
with tbl as
(
select 'steve' "NAME", 2000 val from dual UNION ALL
select 'john' "NAME", 4000 val from dual UNION ALL
select 'peter' "NAME", 270 val from dual UNION ALL
select 'peter' "NAME", 270 val from dual UNION ALL
select 'peter' "NAME", 90 val from dual UNION ALL
select 'peter' "NAME", 450 val from dual UNION ALL
select 'hary' "NAME", 2772 val from dual UNION ALL
select 'may' "NAME", 2227.5 val from dual UNION ALL
select 'tom' "NAME", 500 val from dual UNION ALL
select 'sia' "NAME", 20000 val from dual
)
select name, val,
sum(val) over (order by name) running_sum
from tbl
order by name;
NAME VAL RUNNING_SUM
----- ---------- -----------
hary 2772 2772
john 4000 6772
may 2227.5 8999.5
peter 450 10079.5
peter 270 10079.5
peter 270 10079.5
peter 90 10079.5
sia 20000 30079.5
steve 2000 32079.5
tom 500 32579.5
ВыМожно видеть, что промежуточные итоги теперь имеют смысл, исходя из того, как они оцениваются вашим предложением о работе с окнами.Все четыре значения для peter
включены в промежуточный итог для каждой из этих строк - потому что это все, что есть в order by
- и что общее количество 450 + 270 + 270 + 90 = 1080 добавляется к итогу предыдущего именииз 8999.5.
Вы можете получить разные значения для каждой строки peter
, включив предложение окна на основе строки:
with tbl as
(
select 'steve' "NAME", 2000 val from dual UNION ALL
select 'john' "NAME", 4000 val from dual UNION ALL
select 'peter' "NAME", 270 val from dual UNION ALL
select 'peter' "NAME", 270 val from dual UNION ALL
select 'peter' "NAME", 90 val from dual UNION ALL
select 'peter' "NAME", 450 val from dual UNION ALL
select 'hary' "NAME", 2772 val from dual UNION ALL
select 'may' "NAME", 2227.5 val from dual UNION ALL
select 'tom' "NAME", 500 val from dual UNION ALL
select 'sia' "NAME", 20000 val from dual
)
select name, val,
sum(val) over (order by name
rows between unbounded preceding and current row) running_sum
from tbl;
NAME VAL RUNNING_SUM
----- ---------- -----------
hary 2772 2772
john 4000 6772
may 2227.5 8999.5
peter 450 9449.5
peter 270 9719.5
peter 270 9989.5
peter 90 10079.5
sia 20000 30079.5
steve 2000 32079.5
tom 500 32579.5
Порядок оценки строк с одинаковым именемвсе еще неопределенным, поскольку в этом аналитическом предложении нет инструкции о том, как разорвать связи.
Весь результат теперь неявно упорядочен (по крайней мере сегодня, с использованием CTE и с моей версией и решениями моего оптимизатора), чтоможет быть не то, что вы хотите;но тогда вы должны иметь явное order by
в любом случае, если порядок имеет значение для вас, что бы это ни было.