Cách sử dụng RANK () trong SQL Server


76

Tôi gặp sự cố khi sử dụng RANK()trong SQL Server.

Đây là mã của tôi:

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

Kết quả cho truy vấn đó là:

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

Kết quả mong muốn của tôi là:

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

Tôi muốn xếp hạng kết quả dựa trên totals. Nếu có cùng giá trị như 181, sau đó hai số sẽ có cùng xRank.


Hãy thử cách này: docs.microsoft.com/en-us/sql/t-sql/functions/rank-transact-sql Bạn cũng có thể muốn xem xét sự khác biệt giữa RANK (Transact-SQL) và DENSE_RANK (Transact-SQL )
Ankursonikajen

Câu trả lời:


85

Thay đổi:

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

đến:

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

Hãy xem ví dụ này:

SQL Fiddle DEMO

Bạn cũng có thể muốn xem xét sự khác biệt giữa RANK (Transact-SQL)DENSE_RANK (Transact-SQL) :

RANK (Giao dịch-SQL)

Nếu hai hoặc nhiều hàng buộc cho một thứ hạng, thì mỗi hàng buộc sẽ nhận được cùng một thứ hạng. Ví dụ: nếu hai nhân viên bán hàng hàng đầu có cùng giá trị SalesYTD, thì cả hai đều được xếp hạng một. Nhân viên bán hàng có SalesYTD cao nhất tiếp theo được xếp thứ ba, vì có hai hàng được xếp hạng cao hơn. Do đó, hàm RANK không phải lúc nào cũng trả về các số nguyên liên tiếp.

DENSE_RANK (Giao dịch-SQL)

Trả về thứ hạng của các hàng trong phân vùng của tập hợp kết quả, không có bất kỳ khoảng trống nào trong xếp hạng. Thứ hạng của một hàng là một cộng với số bậc riêng biệt đứng trước hàng được đề cập.


Tôi muốn tổng số cao nhất là không. 1 và từ thứ hai đến cao nhất là số 2 ... câu trả lời của bạn không thành công nhưng vẫn cảm ơn.
Prince Jea

Thay đổi ASC thành DESC như trong DEMO.
Adriaan Stander

1
SQL Fiddle DEMO của bạn không còn hoạt động nữa. Có lẽ vì fiddle hiện đang hỗ trợ SQL Server 2017 và không năm 2008.
Matthieu Cormier

20

Để trả lời tiêu đề câu hỏi của bạn, "Cách sử dụng Xếp hạng () trong SQL Server", đây là cách nó hoạt động:

Tôi sẽ sử dụng tập hợp dữ liệu này làm ví dụ:

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)

Bạn có một phân vùng về cơ bản chỉ định nhóm.

Trong ví dụ này, nếu bạn phân vùng theo cột2, hàm xếp hạng sẽ tạo xếp hạng cho các nhóm giá trị cột2. Sẽ có các cấp bậc khác nhau cho các hàng có column2 = 'SKA' so với các hàng có column2 = 'SKB', v.v.

Các cấp bậc được quyết định như thế này: Thứ hạng cho mọi bản ghi là một cộng với số bậc đứng trước nó trong phân vùng của nó. Thứ hạng sẽ chỉ tăng lên khi một trong các trường bạn đã chọn (ngoài (các) trường được phân vùng) khác với các trường đứng trước nó. Nếu tất cả các trường đã chọn đều giống nhau, thì các cấp bậc sẽ ràng buộc và cả hai sẽ được gán giá trị, một.

Biết điều này, nếu chúng tôi chỉ muốn chọn một giá trị từ mỗi nhóm trong cột hai, chúng tôi có thể sử dụng truy vấn sau:

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

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

Kết quả:

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

Bạn phải sử dụng DENSE_RANK thay vì RANK. Sự khác biệt duy nhất là nó không để lại khoảng trống. Bạn cũng không nên phân vùng theo Contender_num, nếu không, bạn đang xếp hạng từng ứng cử viên trong một nhóm riêng biệt, vì vậy mỗi ứng cử viên được xếp hạng 1 trong các nhóm tách biệt của họ!

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

Một gợi ý cho việc sử dụng StackOverflow, vui lòng đăng dữ liệu mẫu và DDL để mọi người có thể giúp bạn sử dụng ít thời gian của họ hơn!

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 () là một thứ hạng không có khoảng trống, tức là nó "dày đặc".

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

RANK () - Nó chứa khoảng cách giữa thứ hạng.

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

0

Bạn đã nhóm theo ContenderNum, không cần phải phân vùng lại bởi nó. Sử dụng Dense_rank () và sắp xếp theo tổng số mô tả. Nói ngắn gọn,

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

câu trả lời này khác với câu trả lời khác như thế nào?
Noel

@ Ramblin'Man Bởi vì nó hoàn toàn khác.
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()là tốt, nhưng nó chỉ định cùng một thứ hạng cho các giá trị bằng nhau hoặc tương tự. Và nếu bạn cần xếp hạng duy nhất, thì ROW_NUMBER () giải quyết vấn đề này

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

-1

Chọn T.Tamil, T.English, T.Maths, T.Total, Dense_Rank () Over (Đặt hàng theo T.Total Desc) làm Std_Rank From (chọn Tamil, English, Maths, (Tamil + English + Maths) là Total From Sinh viên) như T

nhập mô tả hình ảnh ở đây


Chúng ta có thể thêm ba chủ đề và đặt thứ hạng cho chủ đề đó.
Rajenthiran T

chúng tôi không thể tính tổng tất cả điểm sinh viên hoặc bất kỳ tài chính nào liên quan đến hàng khôn ngoan, trong truy vấn này hữu ích cho hoạt động đó.
Rajenthiran T
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.