一起使用ORDER BY和DISTINCT时出现SQL Server问题

时间:2010-05-14 08:33:12

标签: sql-server group-by distinct

我遇到了两个问题,第一个问题是我开始时的两个问题。 GroupID是一个将产品保持在一起的字符串(Name_Year together),相同的产品但不同的大小。 如果我在tblReview中有三个评论,并且他们都有相同的GroupID我想要返回3.我的问题是,如果我有三个产品具有不同的ProductID但是相同的GroupID,并且我添加三个评论到该GroupID我得到9个返回(3 * 3)。如果我只有一个具有相同GroupID的产品和三个可用的评论(1 * 3 = 3返回)

第二个问题是如果我有ORDER BY CASE价格我也必须添加GROUP BY Price然后我没有得到我想要的DISTINCT效果。那就是展示具有唯一GroupID的产品。

这是查询,希望有人能帮助我。

ALTER PROCEDURE GetFilterdProducts
@CategoryID INT, @ColumnName varchar(100)

AS
SELECT   COUNT(tblReview.GroupID) AS ReviewCount, 
    COUNT(tblComment.GroupID) AS CommentCount, 
    Product.ProductID, 
    Product.Name,
    Product.Year,
    Product.Price,
    Product.BrandID, 
                Product.GroupID, 
                AVG(tblReview.Grade) AS Grade


FROM            Product LEFT JOIN
                         tblComment ON Product.GroupID = tblComment.GroupID LEFT JOIN
                         tblReview ON Product.GroupID = tblReview.GroupID


WHERE        (Product.CategoryID = @CategoryID)

GROUP BY Product.ProductID, Product.BrandID, Product.GroupID, Product.Name, Product.Year, Product.Price

HAVING COUNT(distinct Product.GroupID) = 1

ORDER BY
  CASE 
  WHEN @ColumnName='Name' THEN Name
  WHEN @ColumnName='Year' THEN Year
  WHEN @ColumnName='Price' THEN Price 
  END

我的表格:

产品: ProductID,Name,Year,Price,BrandID,GroupID

tblReview: ReviewID,Description,Grade,ProductID,GroupID

tblComment: CommentID,Description,ProductID,GroupID

我认为我的问题是,如果我有三个具有相同名称的GroupID,那么产品中的前Nike_2010和我在tblReview中有三个评论计算包含Nike_2010的产品中的第一行计算tblReview中有多少评论相同GroupID,Nike_2010,然后是包含Nike_2010的Product中的第二行,然后一次又一次地执行相同的计数,结果为9行。我该如何避免?

2 个答案:

答案 0 :(得分:0)

对于初学者来说,因为你加入了多个表格,所以你最终会得到所有表格的交叉产品。然后,您的计数将返回包含该列中数据的行的总计数。请考虑以下示例:

- PRODUCTS -   -- COMMENTS --    --- REVIEWS ---
 Key | Name     Key | Comment     Key | Review
 1   | A        1   | Foo         1   | Great
 2   | B        1   | Bar         1   | Wonderful

查询

SELECT PRODUCTS.Key, PRODUCTS.Name, COMMENTS.Comment, REVIEWS.Review
FROM PRODUCTS
LEFT OUTER JOIN COMMENTS ON PRODUCTS.KEY = COMMENTS.KEY
LEFT OUTER JOIN REVIEWS ON PRODUCTS.KEY = REVIEWS.KEY

将产生以下数据:

 Key | Name | Comment | Review
 1   | A    | Foo     | Great
 1   | A    | Foo     | Wonderful
 1   | A    | Bar     | Great
 1   | A    | Bar     | Wonderful
 2   | B    | NULL    | NULL

因此,以这种格式计算

SELECT PRODUCTS.Key, PRODUCTS.Name, COUNT(COMMENTS.Comment), COUNT(REVIEWS.Review)
FROM PRODUCTS
LEFT OUTER JOIN COMMENTS ON PRODUCTS.KEY = COMMENTS.KEY
LEFT OUTER JOIN REVIEWS ON PRODUCTS.KEY = REVIEWS.KEY
GROUP BY PRODUCTS.Key, PRODUCTS.Name

会给你

Key | Name | Count1 | Count2
1   | A    | 4      | 4
2   | B    | 0      | 0

因为它正在计算由连接生成的表中的每一行!

相反,您希望在子查询中将每个表单独计算,然后再加入它,如下所示:

SELECT PRODUCTS.Key, PRODUCTS.Name, ISNULL(CommentCount.NumComments, 0),
       ISNULL(ReviewCount.NumReviews, 0)
FROM PRODUCTS
LEFT OUTER JOIN (SELECT Key, COUNT(*) as NumComments
                 FROM COMMENTS
                 GROUP BY Key) CommentCount on PRODUCTS.Key = CommentCount.Key
LEFT OUTER JOIN (SELECT Key, COUNT(*) as NumReviews
                 FROM REVIEWS
                 GROUP BY Key) ReviewCount on PRODUCTS.Key = ReviewCount.Key

将生成以下内容

Key | Name | NumComments | NumReviews
1   | A    | 2           | 2
2   | B    | 0           | 0

至于你提到的“DISTINCT效应”,我并不确定我会效仿。你能详细说一下吗?

答案 1 :(得分:0)

关于第二个问题 - 你不能用相同的CASE声明分组吗?但是,您不应该在结果列表中包含价格字段。