SQL Server 排名

通过使用窗口化函数ROW_NUMBER、RANK、DENSE_RANK和NTILE,可以让SQL对结果进行计数,从而确定每一行在结果集(或分区)中的具体位置。

理论部分

  • ROW_NUMBER:所有行都具有唯一的编号。
  • RANK:如果多个行具有相同的的顺序值,则允许这些行具有相同的值,但是对ROW_NUMBER值重新开始计数。例如,排名第一的是n个具有相同最高销售额的销售人员,而排名第二的是从n+1的RANK值开始的销售人员。
  • DENSE_RANK:仍然是具有相同顺序值就有相同的值,但排名始终是递增的。例如排名第二的销售人员的排名始终是2,而不考虑有多少个排名并列第一的销售人员。
  • NTILE:讲总的结果划分为x个类别,从1-x开始对这些类别排名。因此,NTILE(4)为第一组 1/4 的结果提供值1,而为第二组 1/4 的结果提供值2,以此类推。

测试脚本

-- 创建测试数据库RankTestDB
USE master
GO

IF EXISTS 
    (SELECT *
    FROM sys.databases
    WHERE name = 'RankTestDB')
BEGIN
    DROP DATABASE RankTestDB;
    PRINT 'Database RankTestDB has been dropped';
END
GO

CREATE DATABASE RankTestDB
GO

USE RankTestDB
GO

-- 创建测试表Foo
IF EXISTS 
    (SELECT *
    FROM sys.objects
    WHERE OBJECT_NAME(object_id) = 'Foo'
        AND SCHEMA_NAME(schema_id) = 'dbo'
        AND OBJECTPROPERTY(object_id, 'IsUserTable') = 1)
BEGIN
    DROP TABLE dbo.Foo;
    PRINT 'Table Foo has been dropped';
END
GO

CREATE TABLE Foo (
    ID INT PRIMARY KEY IDENTITY,
    Score INT DEFAULT(CAST(RAND()*101 AS INT))
)
GO

-- 向测试表Foo插入测试数据
DECLARE @i INT = 0;

WHILE (@i < 200)
BEGIN
INSERT INTO Foo DEFAULT VALUES;
SET @i = @i + 1;
END

-- 使用ROW_NUMBER、RANK、DENSE_RANK、NTILE查询
SELECT
    ROW_NUMBER() OVER (ORDER BY Score DESC) AS RowNumber,
    RANK() OVER (ORDER BY Score DESC) AS RankNumber,
    DENSE_RANK() OVER (ORDER BY Score DESC) AS DenseRankNumber,
    NTILE(4) OVER (ORDER BY Score DESC) AS Quartile,
    Foo.*
    FROM Foo


运行结果

《SQL Server 排名》 开始10条数据
《SQL Server 排名》 最后10条数据

参考

《SQLServer2012编程入门经典(第4版)》

    原文作者:银冰雪千载
    原文地址: https://www.jianshu.com/p/e47c74bca735
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞