Reputation: 853
I have asked a question with the same query earlier but this time the question is different so I am posting another question. Below is the sql stored procedure query.
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
This is the query for 1 day. I have changed the table structure and now it is like this,
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
On Monday, value for all other days will be Null. Now for Monday the rating selected is Rating_Monday. Everything works fine. In the above query there are two important parts which are,
ISNULL(AVG([Rating].[Rating_Monday]), 0) AverageRating
COUNT([Rating].[Rating_Monday]) RatingCount
Average is selected absolutely fine but RatingCount is wrong because it is selected according to row count and does not check for the Null value.
Upvotes: 0
Views: 107
Reputation: 167
COUNT(expression) evaluates expression for each row in a group and returns the number of nonnull values.
You may look into using the OVER clause : COUNT(EmployeeID) OVER (PARTITION BY DepartmentID) AS EmployeesPerDept
See COUNT (Transact SLQ) for more information.
Upvotes: 2
Reputation: 93704
To count use condition aggragate
logic.
Case statement
will convert your NULL
values to 0
on that put a SUM aggregate
which will help you to count the rows only those are 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
Upvotes: 0
Reputation: 2016
Using a case can solve this.
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
Upvotes: 1
Reputation: 7344
Try this for the count:
sum(case when [Rating].[Rating_monday] is null then 0 else 1 end)
Upvotes: 1