【问题标题】:How to get AVG in CASE with condition?如何在有条件的情况下获得 AVG?
【发布时间】:2014-03-24 21:21:06
【问题描述】:

我有一个包含整数值的表。 它们可以是负数、0、正数和 NULL。 我需要将 NULL 视为 0,计算给定日期的平均值,如果平均值小于 0,则将 0 放在那里。

我的查询如下:

select
    Id, 
    ValueDate,
    case 
        when avg(isnull(Value, 0)) > 0 then avg(isnull(Value, 0))
        else 0
    end AvgValue
from SomeTable
where ValueDate = @givenDate
group by Id, ValueDate

如何避免在case语句中定义双重聚合函数(聚合语句可能要复杂得多)?

【问题讨论】:

  • 我很确定SQL Server 将缓存函数执行的结果,否则您的AVG 计算不会被执行两次。
  • 如果 TSQL 有一个标量 MAX() 函数,将会有一个简单的解决方案。也许您可以实现自己的:stackoverflow.com/questions/124417/…

标签: sql tsql case average


【解决方案1】:

我认为最大的功能可以帮助你:

select
    Id, 
    ValueDate,
    greatest(avg(isnull(Value, 0)),0) AvgValue
from SomeTable
where ValueDate = @givenDate
group by Id, ValueDate

【讨论】:

  • 问题是关于如何处理此类案件的概念。在那里成像而不是 AVG 有一些函数调用。
  • 您能否分享一个指向greatest 函数文档的链接,用于T-SQL?我没用过,也找不到官方参考。
  • 嗯。看起来它不存在......但你可以定义它。有一个例子:sqlservercentral.com/Forums/Topic489858-338-1.aspx
【解决方案2】:

这是一个解决方案,无需创建任何非内置函数的实现。我知道您的示例会更复杂,但这只是一个想法:

CREATE TABLE DataSource
(
    [ID] TINYINT
   ,[Value] INT
)

INSERT INTO DataSource ([ID], [Value])
VALUES (1, 2)
      ,(1, 0)
      ,(1, NULL)
      ,(1, 98)
      ,(1, NULL)
      ,(2, -4)
      ,(2, 0)
      ,(2, 0)
      ,(2, NULL)

SELECT [ID]
      ,MAX([Value])
FROM
(
  SELECT  [ID]
         ,AVG(COALESCE([Value],0))
  FROM DataSource
  GROUP BY [ID]
  UNION ALL
  SELECT DISTINCT [ID]
                 ,0
  FROM DataSource
) Data([ID],[Value])
GROUP BY [ID]

这是小提琴 - http://sqlfiddle.com/#!6/3d223/14

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    • 2020-07-18
    • 1970-01-01
    • 2017-10-29
    相关资源
    最近更新 更多