web-dev-qa-db-ja.com

集計関数を使用したSQL GROUP BY CASEステートメント

次のような列があります。

CASE
    WHEN col1 > col2 THEN SUM(col3*col4)
    ELSE 0
END AS some_product

そして、GROUP BY句に入れたいのですが、列に集約関数があるため、これが問題を引き起こすようです。この場合、some_productなどの列エイリアスをGROUP BYする方法はありますか、またはこれをサブクエリに入れてグループ化する必要がありますか?

40
Bryan Ward

私が推測するのは、あなたが本当にGROUP BY some_productを望んでいないということです。

答え:「この場合、some_productなどの列エイリアスをGROUP BYする方法はありますか、またはこれをサブクエリに入れてグループ化する必要がありますか?」 is:列エイリアスをGROUP BYすることはできません。

列エイリアスが割り当てられているSELECT句は、GROUP BY句の後まで処理されません。インラインビューまたは共通テーブル式(CTE)を使用して、結果をグループ化できるようにすることができます。

インラインビュー:

select ...
from (select ... , CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END AS some_product
   from ...
   group by col1, col2 ... ) T
group by some_product ...

CTE:

with T as (select ... , CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END AS some_product
   from ...
   group by col1, col2 ... )
select ...
from T
group by some_product ... 
50

Shannon's answer は技術的には正しいですが、やり過ぎのように見えます。

簡単な解決策は、合計をcaseステートメントの外側に置く必要があるということです。これはトリックを行う必要があります:

_sum(CASE WHEN col1 > col2 THEN col3*col4 ELSE 0 END) AS some_product
_

基本的に、古いコードは、各行に対してsum(X*Y)を個別に実行するようにSQLに指示します(グループ化できない独自の回答を各行に残します)。

私が書いたコード行は、あなたが望むものである和の積を取ります。

34
user2076246

他の値でグループ化する場合、現在の値ではなく、

としてそれを書く

Sum(CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END) as SumSomeProduct

もしも、あなたがgroup By内部式、(col3*col4)その後

書きます group Byは、SUM...を含まない式と一致します。

Select Sum(Case When col1 > col2 Then col3*col4 Else 0 End) as SumSomeProduct
From ...

Group By Case When col1 > col2 Then col3*col4 Else 0 End 

最後に、実際の集計でグループ化する場合

Select SumSomeProduct, Count(*), <other aggregate functions>
From (Select <other columns you are grouping By>, 
      Sum(Case When col1 > col2 
          Then col3*col4 Else 0 End) as SumSomeProduct
      From Table
      Group By <Other Columns> ) As Z
Group by SumSomeProduct
2
Charles Bretana