我正在尝试按评分选择产品评论数,评分为0 - 5.
以下基本选择有效,但不会给出基础表中不存在的评级计数。
SELECT Rating, COUNT(*) AS 'Reviews' FROM ProductReviews
WHERE ProductID = 'product1'
GROUP BY Rating
我尝试使用CTE生成缺少的结果,使用外部联接加入到Review表,只要我尝试包含“group by”表达式,结果就会回落以匹配基本查询的结果
(我已经检查过CTE确实生成了所有必需值)。
BEGIN
DECLARE @START AS INT = 0;
DECLARE @END AS INT = 5;
WITH CTE_Ratings AS
(
SELECT @START as cte_rating
UNION ALL
SELECT 1 + cte_rating
FROM CTE_Ratings
WHERE cte_rating < @END
)
SELECT
cte_rating AS 'ReviewRating'
, ISNULL(COUNT(*), 0) AS 'ReviewCount'
FROM CTE_Ratings
LEFT OUTER JOIN Reviews ON Reviews.Rating = cte_rating
WHERE ProductReviews.ProductID = 'product1'
AND cte_rating BETWEEN @START AND @END
GROUP BY cte_rating
END
(我还尝试构建一个包含所需值的临时表,加入到Review表中,结果相同)。
如果是上述两个查询,结果为:
Rating Reviews
0 1
3 3
4 9
5 47
而我想要获得相同数据的是:
Rating Reviews
0 1
1 0
2 0
3 3
4 9
5 47
有人建议何时添加Group By聚合函数导致查询失败,或者如何改进?
答案 0 :(得分:2)
WHERE将OUTER JOIN更改为INNER JOIN,因为您正在对外部表中的可选行进行过滤。
因此,将外部表过滤器移动到JOIN
此外,您已经在CTE的开始和结束之间进行过滤
WITH ...
-- CTE here
SELECT
C.cte_rating AS 'ReviewRating'
, ISNULL(COUNT(PR.Rating), 0) AS 'ReviewCount'
FROM
CTE_Ratings C
LEFT OUTER JOIN
ProductReviews PR ON C.cte_rating= PR.Rating AND PR.ProductID = 'product1'
GROUP BY
C.cte_rating
更清楚的是,你实际上是在做这个
WITH ...
-- CTE here
SELECT
C.cte_rating AS 'ReviewRating'
, ISNULL(COUNT(PR.Rating), 0) AS 'ReviewCount'
FROM
CTE_Ratings C
LEFT OUTER JOIN
(
SELECT PR.Rating
FROM ProductReviews
WHERE ProductID = 'product1'
) PR ON C.cte_rating= PR.Rating
GROUP BY
C.cte_rating