需要有效查询总和和

时间:2019-06-28 09:30:58

标签: sql oracle sum

我有一个SQL查询来选择以下情况下的金额总和。

有些经理负责许多地点的销售。所有地点的所有经理的销售金额都存储在同一表中。 我要从总表中选择“经理”名称,地点总数和他的总数。

以下是我所拥有的SQL。这是工作。但是考虑到表中有10万条记录,寻求一种更有效的实现方式。

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;

表格数据和预期输出数据

2 个答案:

答案 0 :(得分:5)

您可以尝试使用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;

这里是正在发生的事情的解释。窗口函数总是以 last 的形式求值。在窗口函数之后唯一执行的是ORDER BY子句。在上述情况下,在GROUP BY求值之后,中间结果中唯一可用的列是Manager_namelocation_nameSUM(sale_amount)。当我们将SUM用作窗口函数时,按管理者划分分区,因此,我们可以找到所有聚集位置中每个管理者的总和。

答案 1 :(得分:1)

如果您接受另一种显示数据的方式,则可以使用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