blu*_*oft 10 sql-server case sql-server-2014
我正在尝试获取按查询分组的特定列的所有行的产品。我发现的大多数例子都指向组合exp,sum和log
exp(sum(log([Column A])))
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是该列包含一些值的零,因此当零传递给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
Run Code Online (Sandbox Code Playgroud)
给定以下结果集:
Id Name Value
_________________________________
1 a 1
2 a 2
3 b 0
4 b 1
Run Code Online (Sandbox Code Playgroud)
我希望得到以下行:
Name Product
_____________
a 2
b 0
Run Code Online (Sandbox Code Playgroud)
所以总而言之......你如何乘以可以包含负数或零值的列中的行?
Eri*_*ing 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;
Run Code Online (Sandbox Code Playgroud)
返回:
Name Product
a 2
b 0
Run Code Online (Sandbox Code Playgroud)
如果您需要一个更通用的解决方案来处理负数和其他边缘情况,请参见Scott Burkow 的The Product Aggregate in T-SQL Versus the CLR。那篇文章中的一个 T-SQL 结构是:
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)
Run Code Online (Sandbox Code Playgroud)
至于为什么你的原始CASE表达式没有按预期工作,来自CASE (Transact-SQL)的文档(强调):
您应该只依赖于标量表达式(包括返回标量的非相关子查询)的 WHEN 条件的评估顺序,而不是聚合表达式。