program story

SQL Server에서 RANK ()를 사용하는 방법

inputbox 2020. 10. 27. 08:08
반응형

SQL Server에서 RANK ()를 사용하는 방법


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합니다.


변화:

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

에:

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

이 예를 살펴보십시오.

SQL 바이올린 데모

RANK (Transact-SQL)DENSE_RANK (Transact-SQL) 의 차이점을 살펴볼 수도 있습니다 .

RANK (Transact-SQL)

두 개 이상의 행이 순위에 동점 인 경우 동률이있는 각 행은 동일한 순위를받습니다. 예를 들어 두 명의 최상위 영업 사원이 동일한 SalesYTD 값을 가지고 있으면 둘 다 1 순위가됩니다. 다음으로 높은 SalesYTD를 가진 영업 사원은 순위가 더 높은 행이 2 개 있으므로 3 위입니다. 따라서 RANK 함수가 항상 연속 정수를 반환하는 것은 아닙니다.

DENSE_RANK (Transact-SQL)

순위에 공백없이 결과 집합의 파티션 내 행 순위를 반환합니다. 행의 순위는 1에 해당 행 앞에 오는 고유 순위의 수를 더한 값입니다.


질문 제목 인 "SQL Server에서 Rank ()를 사용하는 방법"에 대한 대답은 다음과 같습니다.

이 데이터 세트를 예로 사용하겠습니다.

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)

기본적으로 그룹화를 지정하는 파티션이 있습니다.

이 예에서 column2로 분할하면 rank 함수가 column2 값 그룹에 대한 순위를 만듭니다. column2 = 'SKA'인 행과 column2 = 'SKB'등의 행에는 다른 순위가 있습니다.

순위는 다음과 같이 결정됩니다. 모든 레코드의 순위는 1에 파티션에서 이전 순위의 수를 더한 값입니다. 순위는 선택한 필드 중 하나 (분할 된 필드 제외)가 이전 필드와 다른 경우에만 증가합니다. 선택한 모든 필드가 동일하면 순위가 동점을 이루고 둘 다 값 1이 할당됩니다.

이를 알면 2 열의 각 그룹에서 하나의 값만 선택하려는 경우 다음 쿼리를 사용할 수 있습니다.

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 데모


You have to use DENSE_RANK rather than RANK. The only difference is that it doesn't leave gaps. You also shouldn't partition by contender_num, otherwise you're ranking each contender in a separate group, so each is 1st-ranked in their segregated groups!

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

A hint for using StackOverflow, please post DDL and sample data so people can help you using less of their own time!

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() is a rank with no gaps, i.e. it is “dense”.

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

RANK()-It contain gap between the rank.

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

You have already grouped by ContenderNum, no need to partition again by it. Use Dense_rank()and order by totals desc. In short,

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() is good, but it assigns the same rank for equal or similar values. And if you need unique rank, then ROW_NUMBER() solves this problem

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

Select T.Tamil, T.English, T.Maths, T.Total, Dense_Rank()Over(Order by T.Total Desc) as Std_Rank From (select Tamil,English,Maths,(Tamil+English+Maths) as Total From Student) as T

enter image description here

참고URL : https://stackoverflow.com/questions/12739208/how-to-use-rank-in-sql-server

반응형