如何在不使用GROUP BY的情况下进行聚合?
问题描述:
我有查询类似下面的如何在不使用GROUP BY的情况下进行聚合?
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 BY
只ATTR1
计算正确TOTAL_QTY
,但因为Oracle需要的唯一原因,我的分组等属性,如果GROUP BY
子句,那么所有SELECT
属性应该也在GROUP BY
条款中。
这意味着每次我需要Table_A的查询中的一个属性时,我也需要将它放在GROUP BY
之内。这不仅看起来很丑陋,而且可能会对性能产生影响,也可能会带来不确切的副作用。
如何重写上述查询来计算每个ATTR1
组中的TOTAL_QTY
,而不使用GROUP BY
子句?
答
使用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
这可能需要调整一下,但是这是基本的想法。
答
尝试:
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的价值是不变的 - 他们是即函数依赖于它。)
答
从您的回复我上面的评论,这听起来像你想要每个值ATTR1
一个组,你只需要该组中的任何值ATTR2
。您只需在您的组查询应用MAX
或MIN
到ATTR2
做到这一点:
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
。
这就是聚合的性质,否则你必须进行分组,否则系统不知道你想要的总数或如何形成行。消除这种影响的唯一方法是在其他列max(attr1),max(attr2)上使用聚合,但是如果attr1和attr2在不同行中具有不同的值,您将很快看到为什么group by是更好的选项同一列 – xQbert 2011-12-23 12:12:31
“Oracle要求如果存在GROUP BY子句,则所有SELECT属性也应该在GROUP BY子句中。”不是事实 - 它们也可以汇总;如果其他值对于所需分组项的给定值将始终保持不变,则可以使用MAX等函数。 – 2011-12-23 12:58:03
你在找什么是不明确的。假设你有两行'attr1'具有相同的值,'attr2'具有不同的值。你希望结果集在这种情况下看起来像什么? – 2011-12-23 13:28:55