Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Запрос на SELECT TOP  [new]
Vasiliev Anton
Member

Откуда:
Сообщений: 21
Доброго времени суток.
Нужна помощь в запросе типа SELECT TOP
Дана таблица
create table #tbl (Item varchar(10), ItemGroup varchar(10), Qnt int)

insert #tbl (Item,ItemGroup,Qnt) values('Товар1','Группа1',3)
insert #tbl (Item,ItemGroup,Qnt) values('Товар2','Группа1',56)
insert #tbl (Item,ItemGroup,Qnt) values('Товар3','Группа1',2)
insert #tbl (Item,ItemGroup,Qnt) values('Товар4','Группа1',85)
insert #tbl (Item,ItemGroup,Qnt) values('Товар5','Группа2',23)
insert #tbl (Item,ItemGroup,Qnt) values('Товар6','Группа2',5)
insert #tbl (Item,ItemGroup,Qnt) values('Товар7','Группа2',6)
insert #tbl (Item,ItemGroup,Qnt) values('Товар8','Группа2',14)
insert #tbl (Item,ItemGroup,Qnt) values('Товар9','Группа2',135)
insert #tbl (Item,ItemGroup,Qnt) values('Товар10','Группа3',63)
insert #tbl (Item,ItemGroup,Qnt) values('Товар11','Группа3',93)
insert #tbl (Item,ItemGroup,Qnt) values('Товар12','Группа3',27)
insert #tbl (Item,ItemGroup,Qnt) values('Товар13','Группа3',12)
insert #tbl (Item,ItemGroup,Qnt) values('Товар14','Группа3',10)
insert #tbl (Item,ItemGroup,Qnt) values('Товар15','Группа3',34)

Необходимо получить TOP 3 товаров с макс. Qtn из каждой группы.
ItemItemGroupQnt
Товар4Группа185
Товар2Группа156
Товар1Группа13
Товар9Группа2135
Товар5Группа223
Товар8Группа214
Товар11Группа393
Товар10Группа363
Товар15Группа334


В BOL предложен вариант запроса
select Item,ItemGroup,Qnt
from (select top 3 * from #tbl where ItemGroup = 'Группа1' order by Qnt desc) t1
union all
select Item,ItemGroup,Qnt
from (select top 3 * from #tbl where ItemGroup = 'Группа2' order by Qnt desc) t2
union all
select Item,ItemGroup,Qnt
from (select top 3 * from #tbl where ItemGroup = 'Группа3' order by Qnt desc) t3


Но как быть, если неизвестно кол-во групп или фильтр выборки не только по группе, а допустим еще и по магазину. Может есть какое-то решение?
23 окт 18, 16:13    [21712483]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на SELECT TOP  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
row_number() over (partition by ItemGroup order by Qnt desc) с последующей фильтрацией.
23 окт 18, 16:20    [21712492]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на SELECT TOP  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1466
invm,

Или with ties...
23 окт 18, 16:28    [21712503]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на SELECT TOP  [new]
iap
Member

Откуда: Москва
Сообщений: 46953
WITH CTE(ItemGroup) AS(SELECT DISTINCT ItemGroup FROM #tbl)
SELECT T.Item,T.ItemGroup,T.Qnt
FROM CTE
CROSS APPLY (SELECT TOP(3) * FROM #tbl TT WHERE TT.ItemGroup=CTE.ItemGroup ORDER BY TT.Qnt DESC) T;
Однако, не проверял!

Сообщение было отредактировано: 23 окт 18, 17:00
23 окт 18, 16:46    [21712527]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на SELECT TOP  [new]
iap
Member

Откуда: Москва
Сообщений: 46953
+

iap
WITH CTE(ItemGroup) AS(SELECT DICTINCT ItemGroup FROM #tbl)
SELECT T.Item,T.ItemGroup,T.Qnt
FROM CTE
CROSS APPLY (SELECT TOP(3) * FROM #tbl TT WHERE TT.ItemGroup=CTE.ItemGroup ORDER BY TT.Qnt DESC) T;

Однако, не проверял!
Какой позор! Написал DISTINCT через "C"! :((

Модератор: Поправил


Сообщение было отредактировано: 23 окт 18, 17:00
23 окт 18, 16:47    [21712532]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на SELECT TOP  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
iap,

автор
Какой позор! Написал DISTINCT через "C"! :((

это всё...
23 окт 18, 17:01    [21712558]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на SELECT TOP  [new]
Vasiliev Anton
Member

Откуда:
Сообщений: 21
iap,

Да, CROSS APPLY...то что нужно.

Благодарю!
24 окт 18, 17:14    [21713974]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на SELECT TOP  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
Vasiliev Anton
Да, CROSS APPLY...то что нужно.
Безусловно.
count(distinct ItemGroup) + 1 проходов по таблице всяко лучше одного с row_number()
24 окт 18, 17:51    [21714033]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на SELECT TOP  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 427
invm правильно говорит, его вариант лучше.
select *
from ( select *, row_number() over (partition by ItemGroup order by Qnt desc) as Pos from #tbl ) t
where Pos <= 3
24 окт 18, 18:52    [21714155]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить