具有相同值的 window 的解析函数 SUM returns 平均值
Analytic Function SUM returns Average for window with same values
我试图编写一个查询,结果是给定值的 运行 总和。但是,当应用 SUM 作为分析函数时,我得到的结果的平均值在 window.
范围内
示例:
考虑以下查询:
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;
结果:
我真正想要的是
我使用 ROWNUM 得到的:
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 rownum) running_sum
from tbl;
第一个结果中显示的 peter running_sum 实际上是 peter 总 running_sum 的平均值。分析函数正在考虑对 peter 使用 window,因为我在 windowing 子句中包含了 "NAME"。但为什么查询结果是 window 的平均值而不是 运行 总和?
检查我的回答。
我为 row_number 添加了一个子查询并对其进行了排序
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
), tbl2 as
(
select row_number() over (order by 1) rn, tbl.* from tbl
)
select name, val,
sum(val) over (order by rn) running_sum
from tbl2;
why is the query resulting in average for the window instead of running sum?
这不是 window 的平均值。在您的 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
您可以看到 运行 总计现在有意义,从它们被 windowing 子句评估的顺序来看。 peter
的所有四个值都包含在每一行的 运行 总计中 - 因为这就是 order by
中的全部 - 总计 450+270+270+90=1080正在添加到以前名称的总计 8999.5 中。
您可以通过包含基于行的 window 子句为每个 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
不管它是什么。
所以,实际发生的是分析函数首先聚合 window 的总计,在本例中为 peter,即 1080,然后将结果添加到前面的行总计 8999.5,最后显示 window.
中每行的总数 (1080 + 8999.5 = 10079.5)
与 window 的平均值无关。
我试图编写一个查询,结果是给定值的 运行 总和。但是,当应用 SUM 作为分析函数时,我得到的结果的平均值在 window.
范围内示例: 考虑以下查询:
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;
结果:
我真正想要的是
我使用 ROWNUM 得到的:
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 rownum) running_sum
from tbl;
第一个结果中显示的 peter running_sum 实际上是 peter 总 running_sum 的平均值。分析函数正在考虑对 peter 使用 window,因为我在 windowing 子句中包含了 "NAME"。但为什么查询结果是 window 的平均值而不是 运行 总和?
检查我的回答。
我为 row_number 添加了一个子查询并对其进行了排序
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
), tbl2 as
(
select row_number() over (order by 1) rn, tbl.* from tbl
)
select name, val,
sum(val) over (order by rn) running_sum
from tbl2;
why is the query resulting in average for the window instead of running sum?
这不是 window 的平均值。在您的 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
您可以看到 运行 总计现在有意义,从它们被 windowing 子句评估的顺序来看。 peter
的所有四个值都包含在每一行的 运行 总计中 - 因为这就是 order by
中的全部 - 总计 450+270+270+90=1080正在添加到以前名称的总计 8999.5 中。
您可以通过包含基于行的 window 子句为每个 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
不管它是什么。
所以,实际发生的是分析函数首先聚合 window 的总计,在本例中为 peter,即 1080,然后将结果添加到前面的行总计 8999.5,最后显示 window.
中每行的总数 (1080 + 8999.5 = 10079.5)与 window 的平均值无关。