#sql #tsql
Вопрос:
Как указано в названии, я хочу выбрать 3 лучших значения, и если подсчитанное значение повторяется, включите его тоже.
SELECT b.planID, count(b.planID) AS PopularPlan FROM dbo.Subscriber as b GROUP BY B.planID ORDER BY count(b.planID) DESC;
Этот вывод возвращает все максимальные значения, например:
PlanID PopularPlan 101 2555 123 2555 432 2390 23 2390 45 2090 12 2080 55 2090
Если бы я использовал ТОП-3, чтобы выбрать ТОП-3, со следующим SQL:
SELECT TOP 3 b.planID, count(b.planID) AS PopularPlan FROM dbo.Subscriber as b GROUP BY B.planID ORDER BY count(b.planID) DESC;
Это вернет следующее:
PlanID PopularPlan 101 2555 123 2555 432 2390
Желаемым результатом в этой ситуации было бы сделать то, что я хочу:
PlanID PopularPlan 101 2555 123 2555 432 2390 23 2390 45 2090
Я понимаю, что ТОП-3 ограничивает только три результата, но, похоже, я не могу придумать подход, как добавить, если это повторится.
Кроме того, если бы я включил В СВЯЗИ:
SELECT TOP 3 WITH TIES b.planID, count(b.planID) AS PopularPlan FROM dbo.Subscriber as b GROUP BY B.planID ORDER BY count(b.planID) DESC;
Результатом в этом случае является:
PlanID PopularPlan 101 2555 123 2555 432 2390 23 2390
При тестировании, если я выберу ТОП-5, появится значение 2090, но я хочу сделать то же самое с ТОП-3, если это возможно, чтобы результат был как есть:
PlanID PopularPlan 101 2555 123 2555 432 2390 23 2390 45 2090 lt;- has to have this value too
Комментарии:
1.
where planid in (select top(3) planid from t group by... order by...)
?
Ответ №1:
DENSE_RANK () — ваш друг:
WITH cteOriginal AS ( SELECT b.planID, count(b.planID) AS PopularPlan FROM dbo.Subscriber as b GROUP BY B.planID ) , cteDenseRank AS ( SELECT *, DENSE_RANK() OVER( ORDER BY PopularPlan DESC) AS DRank FROM cteOriginal ) SELECT planID, PopularPlan FROM cteDenseRank WHERE DRank lt;= 3 ORDER BY PopularPlan DESC ;
Предположительно, вы могли бы объединить два CTE вместе, но я никогда точно не знаю, как функции OVER взаимодействуют с GROUP BY, поэтому я сделал это немного более длинным способом.
Лично я могу сказать, что с тех пор, как оконные функции ROW_NUMBER (), RANK() и DENSE_RANK() появились в T-SQL (2008?) Я теперь почти никогда не пользуюсь ТОПОМ.
Отредактировано — DENSE_RANK() Для отображения лучших результатов.
Комментарии:
1. @Marius Извините, переместите предложение вашего исходного запроса ORDER BY в конец окончательного оператора SELECT (но перед «;»). Я тоже отредактирую свой ответ … Хорошо, я это исправил.
2. ждать… нашел еще одну опечатку. Сейчас должно быть хорошо. Хорошо, теперь проверка синтаксиса принимает его.
3. Я внес изменения в последнюю строку (ПО ПОРЯДКУ), которые должны исправить самую последнюю ошибку. Но я не могу это проверить, потому что у меня нет таблиц или исходных данных.
4. @Мариус Да. Я сделал некоторые тестовые данные и таблицы, проблема в том, что я пропустил DESC в вашем первоначальном ЗАКАЗЕ, я также должен добавить это в DENSE_RANK ()… Хорошо, я изменил DENSE_RANK() на
OVER( ORDER BY PopularPlan DESC)
, и это, похоже, работает в моем тестировании.5. Спасибо, это решило проблему. Это был поучительный опыт. Я вам очень благодарен! Спасибо!