Sql 当它等于null时,如何使列输出为零?

Sql 当它等于null时,如何使列输出为零?,sql,sql-server-2008,Sql,Sql Server 2008,我有一个问题,在那里我得到了一些评分的平均值 这是正确的 WITH row_avg_table(avg_rating,employee, approveddate) AS (SELECT (SELECT AVG(rating) FROM ( VALUES (CAST(c.rating1 AS float)), (CAST(c.rating2 AS float)), (CAST(c.rating3 AS float)), (CAST(c.rating4 AS float)), (CAST(c.r

我有一个问题,在那里我得到了一些评分的平均值 这是正确的

WITH row_avg_table(avg_rating,employee, approveddate) AS
(SELECT
(SELECT AVG(rating)
FROM (
VALUES (CAST(c.rating1 AS float)), (CAST(c.rating2 AS float)), (CAST(c.rating3 AS float)), 
(CAST(c.rating4 AS float)), (CAST(c.rating5 AS float)) ) AS v (rating)
WHERE v.rating > 0) avg_rating,
employee,approveddate
FROM CSEReduxResponses c)
SELECT employee,
avg(avg_rating) as average_rating
FROM row_avg_table
where month(approveddate)=2014
AND year(approveddate)=6
GROUP BY employee;
我遇到的问题是,当评分为1-5时,所有的评分都是0。 现在它给了我'null',我希望它在这个特殊场合显示0。 例如,我有下面的数据

create table CSEReduxResponses (rating1 int, rating2 int, rating3 int, rating4 int, rating5 int,
                                approveddate datetime,employee int)

insert into CSEReduxResponses (rating1 , rating2  ,rating3 , rating4 , rating5 ,
                                approveddate, employee )
values 
(5,4,5,1,4,'2014-06-18',1),
(5,4,5,1,0,'2014-06-18',1),
(0,0,0,0,0,'2014-06-19',3);

因此,对于employee=3 average_rating=0

来说,如果使用下面的
ISNULL
函数会怎么样

SELECT ISNULL(AVG(rating),some_default_value)
SELECT AVG(case when rating = 0 then 1 else rating end)
(或)
情况
如下

SELECT ISNULL(AVG(rating),some_default_value)
SELECT AVG(case when rating = 0 then 1 else rating end)
使用

如果
Rating1
null
,则它将替换为默认值
0
。同样,您可以检查其他字段。
COALESCE
ISNULL
T-SQL函数用于返回输入参数中的第一个非null表达式,但是您可以找到它们之间的差异不大


有关的更多详细信息您遇到的问题是
WHERE v.rating>0
子句。如果评级为
0
,则将不返回任何值-并且无法计算零的平均值,因此返回
null
。只需删除此子句,或者如果要过滤负值,请将其更改为
,其中v.rating>=0

如果您使用
0
来存储不希望影响评级的值(就像您在提供的第二个示例中所做的那样),这将不起作用-您将不得不遍历输出并用0替换空值。您可以将第一个查询的结果复制到临时表/表变量中,并进行替换,例如

select employee, rating = isnull(t.rating, 0)
from #temptable t

或者类似的东西。

在这方面使用CTE没有好处。您正在使用交叉应用和值取消激活非规范化表。要获得与您使用的unpivot命令等效的命令,其中。。。不为NULL,但假设您确保所有5个值都存在,以避免计算中出现偏差,因此我建议:

SELECT
      employee
    , AVG(isnull(rating,0)) AS avg_rating
FROM CSEReduxResponses c
      CROSS APPLY (
            VALUES (CAST(c.rating1 AS float))
            , (CAST(c.rating2 AS float))
            , (CAST(c.rating3 AS float))
            , (CAST(c.rating4 AS float))
            , (CAST(c.rating5 AS float))
            ) AS ca1 (rating)
WHERE approveddate >= '20140601'
      AND approveddate < '20140701'
GROUP BY
      employee
;
见:


另外:我鼓励您不要使用数据函数来促进where条件。避免对数据使用函数允许使用索引。这里您只需要一个简单的日期范围(我使用了YYYYMMDD,因为它是sql server最安全的格式)。

。。。您是否有
null
0
?它们不是一回事<代码>平均值(…)将忽略
null
,但不会忽略
0
(原因显而易见)。平均净值的平均值与总体平均值不同,所以你想要平均日平均值、月平均值还是其他什么?您的结果行应该是什么样子?我认为这可能更接近OP需要的,但是您需要将
ISNULL
移动到
AVG
的外部-如果您多次添加
0
,您将降低结果,而
AVG
聚合将忽略
null
值(您可能还必须使用
null如果(…)
零来获取null行…。请注意,如果可能,最好使用诸如
COALESCE(…)
(而不是
IFNULL(…)
)之类的db不可知函数。我不确定这是否正确。如果样本大小为5(5列未插入到5行)而且样本大小对结果很重要,那么AVG()中的isnull是至关重要的。事实上,最初我使用了unpivot的等效方法,即使用交叉应用中的where子句排除null值(请参阅)只有认识到这种潜在的偏见。因此,我认为如果没有用户3591637的更多输入,我们无法确定isnull应该放在哪里。关于coalesce-v-isnull的争论只是一场争论。IFnull适用于MySQL,在这里不相关。当然,我同意使用coalesce()对那些处理多个dbms的人是有用的.但这不是对与错的问题。
| EMPLOYEE | AVG_RATING |
|----------|------------|
|        1 |        3.4 |
|        3 |          0 |