Как ВЫБРАТЬ ОТЛИЧНУЮ информацию с информацией TOP 1 и порядком ОТ лучшей 1 информации

У меня есть 2 таблицы, которые похожи:

CustomerInfo(CustomterID, CustomerName)
CustomerReviews(ReviewID, CustomerID, Review, Score)

Я хочу искать обзоры строку и возврат CustomerInfo.CustomerID и CustomerInfo.CustomerName. Однако я только хочу показать отличный CustomerID и CustomerName наряду со всего одним из их CustomerReviews.Reviews и CustomerReviews.Score. Я также хочу заказать CustomerReviews.Score.

Я не могу выяснить, как сделать это, так как клиент может оставить несколько обзоров, но я только хочу список клиентов с их самым высоким выигранным обзором.

Какие-либо идеи?

5
задан Will Eddins 9 February 2015 в 14:59
поделиться

3 ответа

Это самая большая проблема с числом n на группу, которая возникала десятки раз при переполнении стека.

Вот решение, которое работает с оконной функцией:

WITH CustomerCTE (
  SELECT i.*, r.*, ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY Score DESC) AS RN
  FROM CustomerInfo i
  INNER JOIN CustomerReviews r ON i.CustomerID = r.CustomerID 
  WHERE CONTAINS(r.Review, '"search"')
)
SELECT * FROM CustomerCTE WHERE RN = 1
ORDER BY Score;

А вот решение, которое более широко работает с брендами РСУБД, которые не поддерживают оконные функции:

SELECT i.*, r1.*
FROM CustomerInfo i
INNER JOIN CustomerReviews r1 ON i.CustomerID = r1.CustomerID 
  AND CONTAINS(r1.Review, '"search"')
LEFT OUTER JOIN CustomerReviews r2 ON i.CustomerID = r2.CustomerID 
  AND CONTAINS(r1.Review, '"search"')
  AND (r1.Score < r2.Score OR r1.Score = r2.Score AND r1.ReviewID < r2.ReviewID)
WHERE r2.CustomerID IS NULL
ORDER BY Score;

Я показываю CONTAINS () , потому что вы должны использовать средство полнотекстового поиска в SQL Server, а не использовать LIKE с подстановочными знаками.

5
ответ дан 14 December 2019 в 13:27
поделиться

Думаю, это должно сработать

select ci.CustomterID, ci.CustomerName, cr.Review, cr.Score
from CustomerInfo ci inner join 
(select top 1*
from CustomerReviews
where Review like '%search%'
order by Score desc) cr on ci.CustomterID = cr.CustomterID 
order by cr.Score
0
ответ дан 14 December 2019 в 13:27
поделиться

Я проголосовал за ответ Билла Карвина, но решил предложить еще один вариант.

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

select *
from [CustomerReviews] r
where [ReviewID] =
(
    select top 1 [ReviewID]
    from [CustomerReviews] rInner
    where rInner.CustomerID = r.CustomerID
    order by Score desc
)
order by Score desc

Я не добавил фильтр поиска строк, но его можно легко добавить.

1
ответ дан 14 December 2019 в 13:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: