Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 需要对总和和总和进行有效查询_Sql_Oracle_Sum - Fatal编程技术网

Sql 需要对总和和总和进行有效查询

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

我有一个sql查询,根据下面的场景选择金额的总和

有一些经理负责许多地点的销售。所有地点的所有经理的销售额存储在同一个表中。 我想从总表中选择经理姓名、地点金额和他的总金额

下面是我拥有的SQL。它正在工作。但是考虑到表中的100k记录,寻找更有效的实现方法

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。这真的很有帮助。你让我开心:非常感谢阿什顿的解决方案。我更喜欢将聚合作为另一列。这个解决方案对我来说是一个很好的学习。再次感谢。