#sql-server
#sql-сервер
Вопрос:
Найдены похожие вопросы, но ни один из них не является достаточно ясным, чтобы решить мою проблему. Мне нужно найти топ-3 для каждой из групп. Этот запрос работает, но только для одного. Мне нужно, чтобы он работал для списка ‘IN (…)’.
SELECT top 3 a.make, a.model, a.colour, b.price, c.dealerCode FROM Dealers c
INNER JOIN Cars a on a.make=c.make
INNER JOIN Prices b on a.make=b.make
WHERE c.dealerName='A' and a.make='VW' and b.price_range='X1'
В идеале я хочу, чтобы мои аргументы были в списке IN, например, и в топ-3 из каждого из них:
WHERE c.dealerName IN ('A', 'B', 'C') and a.make IN ('VW','FIAT','Volvo') and b.price_range ='X1'
Хотя это будет работать с IN, это даст мне только верхние 3 из всего списка, в то время как мне нужны верхние 3 из каждой комбинации dealer / make.
(немного упрощенный пример)
(на данный момент мне нужны только верхние 3 из каждого, в каком бы порядке они ни находились) Я подозреваю, что мне нужно использовать GROUP BY, но не могу заставить это работать. Спасибо
Комментарии:
1. Откуда берутся значения для
('A', 'B', 'C')
etc. ?2.
IN
работает. Отправленный вами запрос будет работать и выдавать строки с любой комбинацией этих значений. В чем ваш вопрос? Чего вы ожидали и что получили? Что этоbest 3 deals
значит?3. Я просто сохранил аргументы простыми. вместо ‘A’ это будет имя сделки в моей таблице базы данных. Для тех, кто понизил рейтинг этого вопроса, я уже несколько часов пытаюсь заставить это работать, просматривая ответы и различные веб-сайты, на которые ссылаются через stackoverflow по аналогичным вопросам
4.
top
Безorder by
имеет мало смысла. Я думаю, вы хотите использовать функцию ранжирования, напримерDENSE_RANK()
5. Я не согласен, top без порядка имеет смысл, если вам просто нужны 3 примера, а не тысяча, как я бы получил в моем случае. Кроме того, порядок не является частью проблемы. Но не стесняйтесь добавлять, если вы знаете ответ на мой вопрос. (моя база данных на самом деле не относится к автомобилям, это просто для того, чтобы было понятно)
Ответ №1:
Кажется, вы ищете что-то вроде этого. В общем табличном выражении (CTE) последовательность row_number присваивается уникальным комбинациям PARTITION BY
c.dealerName, a.make, b.price_range
, а порядок не указан, т.Е. ORDER BY
Равен (выберите null). Для удаления дубликатов выбирается только 1 строка для каждого триплета (dealerName, make, price_range). Используя дублированный результат первого CTE, другой номер строки присваивается уникальным комбинациям dealerName и make . Затем для каждой группы выбираются «верхние 3» (dealerName, Make), ограничивая значение номера строки ‘dm_rn’ во внешнем запросе значением <=3.
with
rn_cte as (
select *, row_number() over (partition by c.dealerName, a.make, b.price_range
order by (select null)) rn
from Dealers c
join Cars a on a.make=c.make
join Prices b on a.make=b.make
where c.dealerName IN ('A', 'B', 'C')
and a.make IN ('VW','FIAT','Volvo')
and b.price_range ='X1'),
dm_cte as (
select *, row_number() over (partition by dealerName, make
order by (select null)) dm_rn
from rn_cte
where rn=1)
select make, model, colour, price, dealerCode
from dm_cte
where dm_rn<=3
order by dealerName, make, price_range;
Комментарии:
1. Это абсолютно блестяще, да, это делает трюк точно. Мне потребовалось некоторое время, чтобы понять, что он делает, и мне пришлось адаптироваться к фактическим именам таблиц.
2. Кроме того, это очень быстро! быстрее, чем мой одноразовый SQL выше
3. Рад, что это помогло! В отличие от большинства вопросов, этот я действительно мог распознать имена make, и все объекты имели смысл. Я знаю, что такое автодилер, лол. Приветствия!