Проблемы с SQL Server при совместном использовании ODER BY и DISTINCT - PullRequest
0 голосов
/ 14 мая 2010

У меня две проблемы, первая проблема - мои две СЧЕТА, с которых я начинаю. GroupID - это строка, которая объединяет продукты (Name_Year вместе), один и тот же продукт, но разного размера. Если у меня есть три отзыва в tblReview, и все они имеют один и тот же GroupID, который я хочу вернуть 3. Моя проблема заключается в том, что если у меня есть три продукта с другим ProductID, но одинаковым GroupID, и я добавляю три отзыва к этому GroupID, я получаю 9 возвратов (3 * 3). Если у меня есть только один продукт с тем же GroupID и тремя отзывами, он работает (1 * 3 = 3 возврата)

Вторая проблема заключается в том, что если у меня есть цена ORDER BY CASE, мне нужно добавить также цену GROUP BY, и тогда я не получу эффект 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, Имя, Год, Цена, BrandID, GroupID

tblReview: ReviewID, описание, класс, ProductID, GroupID

tblComment: CommentID, описание, ProductID, GroupID

Я думаю, что моя проблема в том, что если у меня есть три GroupID с одинаковым именем, например, Nike_2010 в Product, и у меня есть три отзыва в tblReview, в котором первая строка в продуктах, содержащих Nike_2010, подсчитывает, сколько отзывов в tblReview с таким GroupID, Nike_2010, а затем вторая строка в Product, содержащая Nike_2010, а затем снова и снова выполняются одинаковые подсчеты, что приводит к 9 строкам. Как мне этого избежать?

Ответы [ 2 ]

0 голосов
/ 14 мая 2010

О второй проблеме - вы не можете группировать по тому же самому утверждению CASE? Тогда в списке результатов не должно быть поля Price.

0 голосов
/ 14 мая 2010

Для начала, поскольку вы объединяете за несколькими столами, в результате вы получите перекрестный продукт всех их. Ваши подсчеты затем вернут общее количество строк, содержащих данные в этом столбце. Рассмотрим следующий пример:

- 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", на который вы ссылаетесь, я не совсем уверен, что буду следовать. Не могли бы вы уточнить немного?

...