Як використовувати RANK () у SQL Server


76

У мене проблема з використанням 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.


Спробуйте це: docs.microsoft.com/en-us/sql/t-sql/functions/rank-transact-sql Ви також можете побачити різницю між RANK (Transact-SQL) та DENSE_RANK (Transact-SQL )
Ankursonikajen

Відповіді:


85

Зміна:

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

до:

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

Погляньте на цей приклад:

SQL-скрипка DEMO

Ви також можете поглянути на різницю між RANK (Transact-SQL) і DENSE_RANK (Transact-SQL) :

RANK (Transact-SQL)

Якщо два чи більше рядків пов’язані для рангу, кожен зв’язаний рядок отримує однаковий ранг. Наприклад, якщо два найкращих продавця мають одне і те ж значення SalesYTD, вони обидва ставляться до одного. Продавець із наступним найвищим показником SalesYTD посідає третє місце, оскільки є два рядки, які вищі. Тому функція RANK не завжди повертає послідовні цілі числа.

DENSE_RANK (Transact-SQL)

Повертає ранг рядків у розділі набору результатів, без пробілів у рейтингу. Ранг рядка дорівнює одиниці плюс кількість різних рангів, які стоять перед відповідним рядком.


Я хочу, щоб найбільшим підсумком було не. 1, а другим до найвищого буде номер 2 ... ваша відповідь не спрацювала, але все одно дякую.
Prince Jea

Змініть ASC на DESC, як у DEMO.
Adriaan Stander

1
Ваша SQL Fiddle DEMO більше не працює. Можливо тому, що скрипка зараз підтримує SQL Server 2017, а не 2008 рік.
Матьє Корм'є

20

Щоб відповісти на заголовок вашого запитання "Як використовувати 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, функція рангу створить ранги для груп значень стовпця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


10

Вам потрібно використовувати DENSE_RANK, а не RANK. Різниця лише в тому, що це не залишає прогалин. Ви також не повинні розділяти за номером претендента, інакше ви класифікуєте кожного претендента в окремій групі, тому кожен займає 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;

3

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]

0

Ви вже згруповані за ContenderNum, не потрібно знову розділяти за ним. Використовуйте Dense_rank () та впорядковуйте за підсумками desc. Коротко,

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

як ця відповідь відрізняється від інших відповідей?
Ноель

@ Ramblin'Man, бо це зовсім інше.
Sliq

0
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

0

RANK()добре, але він присвоює однаковий ранг для рівних або подібних значень. І якщо вам потрібен унікальний ранг, тоді ROW_NUMBER () вирішує цю проблему

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

-1

Виберіть T.Tamil, T.English, T.Maths, T.Total, Dense_Rank () Over (Order by T.Total Desc) як Std_Rank From (виберіть Tamil, English, Maths, (Tamil + English + Maths) як Total From Студент) як T

введіть тут опис зображення


Ми можемо додати три теми і встановити для цього рейтинг.
Rajenthiran T

у цьому запиті, корисному для цієї операції, ми не можемо підсумувати всі оцінки студентів чи будь-які пов’язані з фінансами питання.
Rajenthiran T
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.