負の値とゼロの値を含む列の行を乗算する方法は?


10

クエリでグループ化された特定の列のすべての行の積を取得しようとしています。私は組み合わせ方のポイントに私を見つけたほとんどの例expsumおよびlog

exp(sum(log([Column A])))

私が抱えている問題は、列に値のゼロが含まれているため、log関数にゼロが渡されたときにこのエラーが発生することです。

無効な浮動小数点演算が発生しました。

case式を使用してこれを回避できると思いましたが、すべてのケースを評価しているように見えるので、それは私が思っているように機能しません...

select 
  Name,
  Product = case 
    when min([Value]) = 0 then 0 
    when min([Value]) <> 0 then exp(sum(log(I))) -- trying to get the product of all rows in this column
  end
 from ids
 group by Name

SqlFiddle

次の結果セットがあるとします。

Id  Name  Value
_________________________________
1   a     1
2   a     2
3   b     0
4   b     1

私は次の行を取得すると予想します:

Name  Product
_____________
a     2
b     0

要約すると...負の値またはゼロの値を含むことができる列の行をどのように乗算しますか?

回答:


13

NULLIFの魔法は、あなたの質問のテストケースのトリックを行うようです。SQL Fiddleとは異なる例を使用したので、それがあなたが望んでいるものかどうかはわかりません。

CREATE TABLE dbo.Ids
(
    Id INT NOT NULL IDENTITY(1, 1),
    Value INT,
    Name NVARCHAR(3)
);
INSERT INTO dbo.Ids ( Name, Value )
VALUES ( 'a', 1 );
INSERT INTO dbo.Ids ( Name, Value )
VALUES ( 'a', 2 );
INSERT INTO dbo.Ids ( Name, Value )
VALUES ( 'b', 0 );
INSERT INTO dbo.Ids ( Name, Value )
VALUES ( 'b', 1 );

SELECT   Name,
         CASE WHEN MIN(Value) = 0 THEN 0
              WHEN MIN(Value) > 0 THEN EXP(SUM(LOG(NULLIF(Value, 0)))) -- trying to get the product of all rows in this column
         END AS Product
FROM     Ids
GROUP BY Name;

戻り値:

Name    Product
a       2
b       0

負の数やその他のエッジケースを処理するより一般的なソリューションが必要な場合は、たとえば、Scott BurkowによるT-SQLの製品集計とCLRの比較を参照してください。その記事のT-SQLの構成の1つは次のとおりです。

EXP(SUM(LOG(NULLIF(ABS([Value]), 0))))
*
IIF(SUM(IIF([Value] = 0, 1, NULL)) > 0, 0, 1)
*
IIF(SUM(IIF([Value] < 0, 1, 0)) % 2 = 1, -1, 1)

CASE(Transact-SQL)のCASEドキュメントから、元の式が期待どおりに機能しなかった理由について(強調を追加):

集計式はなく、スカラー式(スカラーを返す非相関サブクエリを含む)のWHEN条件の評価順序のみに依存する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.