2014-11-06 2 views
0

рассмотрим таблицу поставщиков, имеющих две coloumn: «VendorName» и «PayableAmount» Я ищу запрос, который возвращает десятку поставщиков, отсортированных по PayableAmount по убыванию и сумме другие подлежащие оплате aMounts как «другие» в 11-й строке. явно сумма PayableAmount из таблицы продавцов shoud будет равна сумме PayableAmount из Query.Сортировка десяти ведущих поставщиков и показ оставшихся поставщиков как «другие»

+2

Было бы очень приятно, если бы мы могли видеть, что вы пробовали в первую очередь. –

ответ

0

Это выполнит запрос, который вы ищете. Во-первых, извлекая в топ-10, а затем UNION Ing, которые приводят с более ранжированных поставщиками, но называть эти 'Other'

WITH rank AS (SELECT 
VendorName, 
PayableAmount, 
ROW_NUMBER() OVER (ORDER BY PayableAmount DESC) AS rn 
FROM vendors) 

SELECT VendorName, 
rn, 
PayableAmount 
FROM 
rank WHERE rn <= 10 

UNION 

SELECT VendorName, 11 AS rn, PayableAmount 
FROM 
    (
    SELECT 'Other' AS VendorName, 
    SUM(PayableAmount) AS PayableAmount 
    FROM 
    rank WHERE rn > 10 
) X11 

ORDER BY rn 

Это было проверено в SQLFiddle.

+0

Я выполнил это. «Другая» строка не является 11-й строкой, потому что ее сумма больше 9-го и 10-го поставщиков в моей таблице. – Behnam

+0

Попробуйте «ЗАКАЗАТЬ ЗА ГОДУ« PayableAmount DESC »в конце. – mjsqu

+0

«Другая» строка, подлежащая выплате, не является наименьшей суммой. поэтому мы не можем этого сделать. – Behnam

0

это на 11-й строке

я не проверить его

declare @i int 
set @i= 
(select sum(x.PayableAmount) 
from 
(select * from table 
except 
select top 10 *from table 
order by PayableAmount desc) as x) 

select 'another',@i 
1

Технически, это можно сделать в одном запросе:

declare @t table (
    Name varchar(50) primary key, 
    Amount money not null 
); 

-- Dummy data 
insert into @t (Name, Amount) 
select top (20) sq.* 
from (
select name, max(number) as [Amount] 
from master.dbo.spt_values 
where number between 100 and 100000 
    and name is not null 
group by name 
) sq 
order by newid(); 

-- The table itself, for verification 
select * from @t order by Amount desc; 

-- Actual query 
select top (11) 
    case when sq.RN > 10 then '<All others>' else sq.Name end as [VendorName], 
    case 
     when sq.RN > 10 then sum(sq.Amount) over(partition by case when sq.rn > 10 then 1 else 0 end) 
     else sq.Amount 
    end as [Value] 
from (
    select t.Name, t.Amount, row_number() over(order by t.Amount desc) as [RN] 
    from @t t 
    ) sq 
order by sq.RN; 

Он будет даже работать на любом SQL Server начиная с 2005 года. Но в реальной жизни я бы предпочел рассчитать эти 2 части отдельно, а затем UNION.

Смежные вопросы