在sql中汇总行和列

时间:2011-12-16 11:03:36

标签: sql database group-by aggregate-functions

我需要总结一些行,在每行上应用一个公式,然后在最后一列中总结所有结果。我想在总列中我没有必要指定以前的公式,但是使用列的名称,我的意思是类似下面的代码(由于total_1,total_2和total_3无法识别,因此不起作用)

SELECT 
    t.id, 
    t.dpt, 
    sum(t1.coefficient * t1.value) AS total_1,
    sum(t2.coefficient * t2.value) AS total_2,
    sum(t3.coefficient * t3.value) AS total_3,
    (total_1 + total_2 + total_3) AS total -- Not recognized
FROM my table t
JOIN table1 t1 ON...
JOIN table2 t2 ON...
JOIN table3 t3 ON...
group by t.id, t.dpt

我知道我可以做类似下面的事情,但它在总和的定义中有一些冗余。

SELECT 
    t.id, 
    t.dpt, 
    sum(t1.coefficient * t1.value) AS total_1,
    sum(t2.coefficient * t2.value) AS total_2,
    sum(t3.coefficient * t3.value) AS total_3,
    sum(t1.coefficient * t1.value + t2.coefficient * t2.value + t3.coefficient * t3.value) AS total
FROM my table t
JOIN table1 t1 ON...
JOIN table2 t2 ON...
JOIN table3 t3 ON...
group by t.id, t.dpt

是否有任何有效的查询可以帮助避免重新定义总列中的列总和?

由于

2 个答案:

答案 0 :(得分:2)

我想到的最简单的方法是:

SELECT *, (total_1 + total_2 + total_3) AS total FROM (
    SELECT 
        t.id, 
        t.dpt, 
        sum(t1.coefficient * t1.value) AS total_1,
        sum(t2.coefficient * t2.value) AS total_2,
        sum(t3.coefficient * t3.value) AS total_3
    FROM my table t
    JOIN table1 t1 ON...
    JOIN table2 t2 ON...
    JOIN table3 t3 ON...
    GROUP BY t.id, t.dpt
) t

<强>加

我已经测试了类似下面的查询(我知道它们有所不同,但你应该自己测试它是找出差异的最好方法)。在每次运行之前,我已执行DBCC DROPCLEANBUFFERSDBCC FREEPROCCACHE。第二次运行在几分钟后执行,差异可能是由于服务器负载造成的。

SET STATISTICS TIME ON

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
go

select t1.col1, sum(i.col2) as s, sum(i.col2) * 4 as smult
from tab1 t1
join tab2 t2 on t1.col1 = t2.col1
group by t1.col1

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
go

select *, s * 4 as smult from (
    select t1.col1, sum(i.col2) as s
    from tab1 t1
    join tab2 t2 on t1.col1 = t2.col1
    group by t1.col1
) t

第一次查询第一次运行:

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 516 ms.
SQL Server Execution Times:
   CPU time = 63 ms,  elapsed time = 3958 ms.

第一次查询第二次运行:

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 374 ms.
SQL Server Execution Times:
   CPU time = 31 ms,  elapsed time = 4152 ms.

第二次查询第一次运行:

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 513 ms.
SQL Server Execution Times:
   CPU time = 94 ms,  elapsed time = 3445 ms.

第二次查询第二次运行:

SQL Server parse and compile time: 
   CPU time = 16 ms, elapsed time = 363 ms.
SQL Server Execution Times:
   CPU time = 125 ms,  elapsed time = 3146 ms.

答案 1 :(得分:0)

最有效的方式(至少在Oracle中)将只是:

SELECT 
    t.id, 
    t.dpt, 
    sum(t1.coefficient * t1.value) AS total_1,
    sum(t2.coefficient * t2.value) AS total_2,
    sum(t3.coefficient * t3.value) AS total_3,
    sum(t1.coefficient * t1.value) +  sum(t2.coefficient * t2.value) + sum(t3.coefficient * t3.value) AS total
FROM my table t
JOIN table1 t1 ON...
JOIN table2 t2 ON...
JOIN table3 t3 ON...
group by t.id, t.dpt

Oracle非常聪明地认识到它已经计算了总和并且没有改变执行计划,所以没有性能损失。

您甚至可以按照建议的方式进行:sum(t1.coefficient * t1.value + t2.coefficient * t2.value + t3.coefficient * t3.value)。它与我认为的表现完全一样。

智能优化器消除了您所谈论的冗余。