2011-12-23 252 views
1

私は、次の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 

私だけATTR1が正しいTOTAL_QTYを計算しますが、Oracleが必要なため、唯一の理由は、私は他の属性をグループ化していますGROUP BYに必要なようなクエリGROUP BY句が存在する場合、すべてのSELECTの属性がすべきことGROUP BY節にもあります。

これは、Table_Aからこのクエリで属性が必要になるたびに、それをGROUP BYに配置する必要があることを意味します。それは醜いだけでなく、パフォーマンスに影響を与える可能性があり、おそらくは副作用を予期しない可能性があります。

GROUP BY句を除いて、それぞれのATTR1グループのTOTAL_QTYを計算するために上記のクエリを書き直すにはどうすればよいですか?

+2

これは集合体の性質なので、グループ化する必要があります。グループ化する必要があるのは、合計するものや行の作成方法がわからないためです。この影響を排除する唯一の方法は、他の列max(attr1)、max(attr2)で集約を使用することですが、attr1とattr2が異なる行に異なる値を持つ場合、group byがより良いオプションである理由をすぐに知ることができます。同じ列 – xQbert

+0

"Oracleでは、GROUP BY句が存在する場合、すべてのSELECT属性もGROUP BY句に含める必要があります。そうではありません - それらは集約することもできます。必要なグループ化項目の所与の値に対して他の値が常に一定であれば、MAXなどの関数を使用できます。 –

+2

あなたが探しているものはあまり定義されていません。 'attr1'には同じ値を持ち、' ​​attr2'には異なる値を持つ2つの行があるとします。この場合、結果セットはどのように見えますか? –

答えて

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 

これは、ビットを微調整する必要があるかもしれませんが、それは基本的な考え方です。

+0

下位互換性のあるウィンドウ集合関数はどれくらいですか? 11gのみ? 10g? – MatBailie

+0

8.xで導入されました –

+2

+1「インライン集約」のこの手法はPostgreSQLとSQL Server 2005+にも適用されます – gbn

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の値が一定であると仮定している - すなわち、それらは機能的にそれに依存している。。)あなたの応答から

+0

'Attr2'、' attr3'などは一意ではありません。 – AppleGrew

+0

@AppleGrew:その答えはあなたの質問に対するDave Costaのコメントに対するあなたの答えと矛盾しているようです。どちらですか? –

+0

そのコメントは 'attr1'のものだけでした。他の属性は別個であってもよく、そうでなくてもよい。 – AppleGrew

1

へ上記の私のコメントは、あなたはATTR1の値ごとに1つのグループがほしいと思っているだけで、そのグループに属するATTR2の任意の値が必要です。あなたは、単にあなたのグループのクエリでATTR2からMAXまたはMINを適用することにより、これを行うことができます。

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のための単一の値を選ぶことでしょう。

関連する問題