不想在COUNT中使用NULL的列

时间:2014-11-25 16:12:02

标签: sql sql-server

我之前用相同的查询问了一个问题,但这次问题不同,所以我发布了另一个问题。下面是sql存储过程查询。

SELECT ROW_NUMBER() OVER (ORDER BY [PostedDate] Desc)AS RowNumber,[Products].[Id], [Name], [Description], [PostedDate], 
       ISNULL(AVG([Rating].[RatingValue]), 0) AverageRating, COUNT([Rating].[RatingValue]) RatingCount
       INTO #DealResults1
       FROM [Products]
       LEFT OUTER  JOIN [Rating] ON [Product].[Id] = [Rating].[ProductId]
       WHERE [City] = CASE WHEN @CityId IS NULL THEN [City] ELSE @CityId END 
       AND [Description] IS NOT NULL  
       Group by [Products].[Id], [Name], [Description], [PostedDate]
       ORDER BY [PostedDate] Desc

这是1天的查询。我已经改变了表结构,现在就是这样,

Id      Rating_Monday      Rating_Tuesday        Rating_Wednesday .......
 1            3.0                NULL                    NULL
 2            3.5                NULL                    NULL
 3            NULL               2.0                     NULL
 4            NULL               3.0                     NULL
 5            NULL               1.5                     NULL
 6            NULL               NULL                    1.0
 7            NULL               NULL                     2.5
 8            NULL               NULL                     4.5

周一,所有其他日子的价值将为空。现在周一选择的评级为Rating_Monday。一切正常。在上面的查询中有两个重要的部分,

ISNULL(AVG([Rating].[Rating_Monday]), 0) AverageRating
COUNT([Rating].[Rating_Monday]) RatingCount

平均值选择绝对正常但是RatingCount错误,因为它是根据行数选择的,并且不检查Null值。

4 个答案:

答案 0 :(得分:2)

COUNT(表达式)计算组中每一行的表达式,并返回非空值的数量

您可以考虑使用OVER子句:COUNT(EmployeeID) OVER (PARTITION BY DepartmentID) AS EmployeesPerDept

有关详细信息,请参阅COUNT (Transact SLQ)

答案 1 :(得分:1)

尝试计算:

sum(case when [Rating].[Rating_monday] is null then 0 else 1 end)

答案 2 :(得分:1)

使用案例可以解决这个问题。

SELECT ROW_NUMBER() OVER (ORDER BY [PostedDate] Desc)AS RowNumber,[Products].[Id], [Name],  [Description], [PostedDate], 
   ISNULL(AVG([Rating].[RatingValue]), 0) AverageRating, 
   SUM(case  when (Rating.RatingValue) is null then 0 else 1 END) RatingCount
   INTO #DealResults1
   FROM [Products]
   LEFT OUTER  JOIN [Rating] ON [Product].[Id] = [Rating].[ProductId]
   WHERE [City] = CASE WHEN @CityId IS NULL THEN [City] ELSE @CityId END 
   AND [Description] IS NOT NULL  
   Group by [Products].[Id], [Name], [Description], [PostedDate]
   ORDER BY [PostedDate] Desc

答案 3 :(得分:0)

计算使用condition aggragate逻辑。

Case statement会将您的NULL值转换为0,只需SUM aggregate {{}}},这将有助于您只计算NOT NULL

SELECT Row_number()OVER (ORDER BY [PostedDate] DESC)        AS RowNumber,
       [Products].[Id],
       [Name],
       [Description],
       [PostedDate],
       Isnull(Avg([Rating].[RatingValue]), 0) AverageRating,
       Sum(CASE WHEN [Rating].[Rating_monday] IS NULL THEN 0 ELSE 1 END) RatingCount
INTO   #DealResults1
FROM   [Products]
       LEFT OUTER JOIN [Rating]
                    ON [Product].[Id] = [Rating].[ProductId]
WHERE  [City] = CASE WHEN @CityId IS NULL THEN [City] ELSE @CityId END
       AND [Description] IS NOT NULL
GROUP  BY [Products].[Id],
          [Name],
          [Description],
          [PostedDate]
ORDER  BY [PostedDate] DESC