如何在不使用`GROUP BY`的情况下进行聚合?

时间:2011-12-23 12:06:46

标签: sql oracle group-by aggregate-functions

我有以下查询

SELECT a.*, b.*

(SELECT ATTR1, ATTR2, sum(QUANTITY) AS TOTAL_QTY,
ATTR3 FROM TABLE_A
WHERE ATTR4 > 0
GROUP BY ATTR1, ATTR2, ATTR3) a,

TABLE_B b

WHERE a.ATTR1 = b.ATTR1
AND a.ATTR2 = b.ATTR2

我需要GROUP BYATTR1来计算正确的TOTAL_QTY,但我将其他属性分组的唯一原因是因为Oracle要求如果存在GROUP BY子句则所有SELECT属性也应该在GROUP BY子句中。

这意味着每次我需要Table_A中的此查询中的属性时,我还需要将其放在GROUP BY中。这不仅看起来很丑陋,而且可能会对性能产生影响,也许会产生不可预见的副作用。

如何在没有TOTAL_QTY子句的情况下重写上述查询来计算每个ATTR1组中的GROUP BY

3 个答案:

答案 0 :(得分:8)

使用Oracle分析功能。将table_a的内嵌视图更改为:

select attr1,
       attr2,
       sum(quantity) over (partition by attr1 order by attr1) as total_qty,
       attr3
from   table_a
where  attr4 > 0

这可能需要调整一下,但这是基本的想法。

答案 1 :(得分:2)

尝试:

SELECT a.*, b.*
from (SELECT ATTR1, 
             max(ATTR2) ATTR2, 
             sum(QUANTITY) AS TOTAL_QTY,
             max(ATTR3) ATTR3 
      FROM TABLE_A
      WHERE ATTR4 > 0
      GROUP BY ATTR1) a,
      TABLE_B b
WHERE a.ATTR1 = b.ATTR1
AND a.ATTR2 = b.ATTR2

(假设对于ATTR1的每个给定值,ATTR2和ATTR3的值是恒定的 - 即它们在功能上依赖于它。)

答案 2 :(得分:1)

从您对上述评论的回复中,您觉得每个ATTR1值都需要一个组,而您只需要属于该组的ATTR2的任何值。您只需在群组查询中应用MAXMINATTR2即可完成此操作:

SELECT a.*, b.*
FROM
(SELECT ATTR1, max(ATTR2) attr2, sum(QUANTITY) AS TOTAL_QTY,
ATTR3 FROM TABLE_A
WHERE ATTR4 > 0
GROUP BY ATTR1, ATTR2, ATTR3) a,
TABLE_B b
WHERE a.ATTR1 = b.ATTR1
AND a.ATTR2 = b.ATTR2

通过这种方式,您可以从群组中的所有人中随意选择ATTR2的单个值。