Sql 需要对总和和总和进行有效查询
我有一个sql查询,根据下面的场景选择金额的总和 有一些经理负责许多地点的销售。所有地点的所有经理的销售额存储在同一个表中。 我想从总表中选择经理姓名、地点金额和他的总金额 下面是我拥有的SQL。它正在工作。但是考虑到表中的100k记录,寻找更有效的实现方法Sql 需要对总和和总和进行有效查询,sql,oracle,sum,Sql,Oracle,Sum,我有一个sql查询,根据下面的场景选择金额的总和 有一些经理负责许多地点的销售。所有地点的所有经理的销售额存储在同一个表中。 我想从总表中选择经理姓名、地点金额和他的总金额 下面是我拥有的SQL。它正在工作。但是考虑到表中的100k记录,寻找更有效的实现方法 SELECT D1.Manager_name, D1.location_name, sum(D1.sale_amount) sale_amount, (select sum(D2.sale_amount) from details D2
SELECT
D1.Manager_name,
D1.location_name,
sum(D1.sale_amount) sale_amount,
(select sum(D2.sale_amount) from details D2 where D1.Manager_name = D2.Manager_name) total_amount
FROM details D1
GROUP BY
D1.Manager_name,
D1.location_name;
表数据和预期输出数据
您可以尝试将SUM用作窗口函数,以替换相关子查询:
SELECT
D1.Manager_name,
D1.location_name,
SUM(D1.sale_amount) sale_amount,
SUM(SUM(D1.sale_amount)) OVER (PARTITION BY D1.Manager_name) total_amount
FROM details D1
GROUP BY
D1.Manager_name,
D1.location_name;
下面是对正在发生的事情的解释。窗口函数总是最后求值。在窗口函数之后执行的唯一内容是ORDERBY子句。在上述情况下,在GROUP BY求值后,中间结果中唯一可用的列是Manager_name、location_name和SUMsale_amount。当我们使用SUM作为窗口函数时,通过管理器分区,我们可以在所有聚合位置上找到每个管理器的总和。如果您接受另一种显示数据的方式,GROUP by子句的扩展将在一次传递中为您提供所需的小计和总和。这里我生成99999行,并在0.03秒内得到输出
with m(manager_name) as (
select 'Mgr '||level from dual connect by level <= 3
)
, l(location_name) as (
select 'Location '||level from dual connect by level <= 3
)
, s(sale_amount) as (
select level from dual connect by level <= 100000/9
)
select
Manager_name,
location_name,
sum(sale_amount) sale_amount
FROM m, l, s
GROUP BY Manager_name,
rollup(location_name);
MANAGER_NAME LOCATION_NAME SALE_AMOUNT
------------ ------------- -----------
Mgr 1 Location 1 61732716
Mgr 1 Location 2 61732716
Mgr 1 Location 3 61732716
Mgr 1 185198148
Mgr 2 Location 1 61732716
Mgr 2 Location 2 61732716
Mgr 2 Location 3 61732716
Mgr 2 185198148
Mgr 3 Location 1 61732716
Mgr 3 Location 2 61732716
Mgr 3 Location 3 61732716
Mgr 3 185198148
哇!像超人一样工作。我看到了解释前后的成本。成本降低了50%。请您解释一下,尽管按其他列分组,SUMxx如何在分区上工作?非常感谢@Tim。这真的很有帮助。你让我开心:非常感谢阿什顿的解决方案。我更喜欢将聚合作为另一列。这个解决方案对我来说是一个很好的学习。再次感谢。