Как использовать RANK() в SQL Server



у меня проблема с использованием RANK() в SQL Server.



вот мой код:



SELECT contendernum,
totals,
RANK() OVER (PARTITION BY ContenderNum ORDER BY totals ASC) AS xRank
FROM (
SELECT ContenderNum,
SUM(Criteria1+Criteria2+Criteria3+Criteria4) AS totals
FROM Cat1GroupImpersonation
GROUP BY ContenderNum
) AS a


результаты для этого запроса:



contendernum    totals    xRank
1 196 1
2 181 1
3 192 1
4 181 1
5 179 1


Каков мой желаемый результат:



contendernum    totals    xRank
1 196 1
2 181 3
3 192 2
4 181 3
5 179 4


Я хочу ранжировать результат на основе totals. Если есть такое же значение, как 181, тогда два числа будут иметь то же самое xRank.

827   8  

8 ответов:

изменения:

RANK() OVER (PARTITION BY ContenderNum ORDER BY totals ASC) AS xRank

to:

RANK() OVER (ORDER BY totals DESC) AS xRank

взгляните на этот пример:

SQL Fiddle DEMO

вы также можете взглянуть на разницу между ранг (Transact-SQL) и DENSE_RANK (Transact-SQL):

ранг (Transact-SQL)

Если две или более строк связывают для ранга, каждая связанная строка получает то же самое ранг. Например, если две лучшие продавцы имеют те же продажи за год на дату значение, они оба занимают одно место. Менеджер по продажам со следующим по величине SalesYTD занимает третье место, потому что есть две строки, которые являются высокий ранг. Поэтому функция RANK не всегда возвращает значение последовательные целые числа.

DENSE_RANK (Transact-SQL)

возвращает ранг строк в разделе результирующего набора, без никаких пробелов в рейтинге. Ранг а строка-это один плюс количество различные ранги, которые приходят перед строкой в вопросе.

чтобы ответить на ваш вопрос название, "как использовать Rank() в SQL Server," вот как это работает:

Я буду использовать этот набор данных в качестве примера:

create table #tmp
(
  column1 varchar(3),
  column2 varchar(5),
  column3 datetime,
  column4 int
)

insert into #tmp values ('AAA', 'SKA', '2013-02-01 00:00:00', 10)
insert into #tmp values ('AAA', 'SKA', '2013-01-31 00:00:00', 15)
insert into #tmp values ('AAA', 'SKB', '2013-01-31 00:00:00', 20)
insert into #tmp values ('AAA', 'SKB', '2013-01-15 00:00:00', 5)
insert into #tmp values ('AAA', 'SKC', '2013-02-01 00:00:00', 25)

у вас есть раздел, который в основном определяет группировку.

в этом примере при разбиении по столбцу 2 Функция rank создает ранги для групп значений столбца 2. Там будут разные ранги для строк, где column2 = 'SKA', чем строки, где column2 = ' SKB ' и так далее.

В ранги решаются так: Ранг для каждой записи равен единице плюс количество рангов, которые стоят перед ней в ее разделе. Ранг будет увеличиваться только тогда, когда одно из выбранных вами полей (кроме секционированных полей) отличается от тех, которые находятся перед ним. Если все выбранные поля одинаковы, то ранги будут привязаны и обоим будет присвоено значение, один.

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

with cte as 
(
  select *, 
  rank() over (partition by column2 
             order by column3) rnk
  from t

) select * from cte where rnk = 1 order by column3;

результат:

COLUMN1 | COLUMN2   | COLUMN3                           |COLUMN4 | RNK
------------------------------------------------------------------------------
AAA     | SKB   | January, 15 2013 00:00:00+0000    |5   | 1
AAA     | SKA   | January, 31 2013 00:00:00+0000    |15  | 1
AAA     | SKC   | February, 01 2013 00:00:00+0000   |25  | 1

SQL DEMO

вы должны использовать DENSE_RANK, а не ранг. Единственная разница в том, что он не оставляет пробелов. Вы также не должны разделять по contender_num, иначе вы ранжируете каждого соперника в отдельной группе, поэтому каждый из них занимает 1-е место в своих сегрегированных группах!

SELECT contendernum,totals, DENSE_RANK() OVER (ORDER BY totals desc) AS xRank FROM
(
SELECT ContenderNum ,SUM(Criteria1+Criteria2+Criteria3+Criteria4) AS totals
FROM dbo.Cat1GroupImpersonation
 GROUP BY ContenderNum
) AS a
order by contendernum

подсказка для использования StackOverflow, пожалуйста, разместите DDL и образцы данных, чтобы люди могли помочь вам использовать меньше своего времени!

create table Cat1GroupImpersonation (
contendernum int,
criteria1 int,
criteria2 int,
criteria3 int,
criteria4 int);

insert Cat1GroupImpersonation select
1,196,0,0,0 union all select
2,181,0,0,0 union all select
3,192,0,0,0 union all select
4,181,0,0,0 union all select
5,179,0,0,0;

DENSE_RANK () - это ранг без пробелов, т. е. он "плотный".

select Name,EmailId,salary,DENSE_RANK() over(order by salary asc) from [dbo].[Employees]

RANK () - содержит разрыв между рангом.

select Name,EmailId,salary,RANK() over(order by salary asc) from [dbo].[Employees]

вы уже сгруппированы по ContenderNum, нет необходимости снова разделять его. Использовать Dense_rank()и порядка по убыванию суммы. Короче говоря,

SELECT contendernum,totals, **DENSE_RANK()** 
OVER (ORDER BY totals **DESC**) 
AS xRank 
FROM
(
   SELECT ContenderNum ,SUM(Criteria1+Criteria2+Criteria3+Criteria4) AS totals
   FROM dbo.Cat1GroupImpersonation
   GROUP BY ContenderNum
) AS a
SELECT contendernum,totals, RANK() OVER (ORDER BY totals ASC) AS xRank FROM
(
SELECT ContenderNum ,SUM(Criteria1+Criteria2+Criteria3+Criteria4) AS totals
FROM dbo.Cat1GroupImpersonation
 GROUP BY ContenderNum
) AS a

RANK() это хорошо, но он присваивает тот же ранг для равных или аналогичных значений. И если вам нужен уникальный ранг, то ROW_NUMBER () решает эту проблему

ROW_NUMBER() OVER (ORDER BY totals DESC) AS xRank

выбрать т. Тамил, т. английский, т. математика, т. Общая, Dense_Rank()над(заказ по т. Общая убыв) как Std_Rank От (выберите Тамил, английский, математика, (Тамил + английский+математика) как всего от студента) как Т Введите описание изображения здесь

Comments

    Ничего не найдено.