我搞不懂它们之间的区别。运行下面的SQL会得到两个相同的结果集。有人能解释一下其中的区别吗?

SELECT ID, [Description], RANK()       OVER(PARTITION BY StyleID ORDER BY ID) as 'Rank'      FROM SubStyle
SELECT ID, [Description], ROW_NUMBER() OVER(PARTITION BY StyleID ORDER BY ID) as 'RowNumber' FROM SubStyle

当前回答

只有在分区中为特定排序值设置了关联时,才会看到差异。

在这种情况下,RANK和DENSE_RANK是确定的,对于排序列和分区列具有相同值的所有行最终将得到相同的结果,而ROW_NUMBER将任意(非确定地)将递增的结果分配给绑定的行。

示例:(所有行都有相同的StyleID,所以都在同一个分区中,在该分区中,前3行按ID排序时是绑定的)

WITH T(StyleID, ID)
     AS (SELECT 1,1 UNION ALL
         SELECT 1,1 UNION ALL
         SELECT 1,1 UNION ALL
         SELECT 1,2)
SELECT *,
       RANK() OVER(PARTITION BY StyleID ORDER BY ID)       AS [RANK],
       ROW_NUMBER() OVER(PARTITION BY StyleID ORDER BY ID) AS [ROW_NUMBER],
       DENSE_RANK() OVER(PARTITION BY StyleID ORDER BY ID) AS [DENSE_RANK]
FROM   T  

返回

StyleID     ID       RANK      ROW_NUMBER      DENSE_RANK
----------- -------- --------- --------------- ----------
1           1        1         1               1
1           1        1         2               1
1           1        1         3               1
1           2        4         4               2

您可以看到,对于三个相同的行,ROW_NUMBER增加,RANK值保持不变,然后跳到4。DENSE_RANK也将相同的秩赋给所有三行,但下一个不同的值被赋值为2。

其他回答

ROW_NUMBER:为以1开头的每一行返回一个唯一的数字。对于具有重复值的行,将任意分配数字。

Rank:为从1开始的每一行分配一个唯一的数字,但有重复值的行除外,在这种情况下,分配相同的排名,并且在每个重复排名的序列中出现一个空白。

我没有做任何关于秩的事情,但是我今天用row_number()发现了这一点。

select item, name, sold, row_number() over(partition by item order by sold) as row from table_name

这将导致一些重复的行号,因为在我的例子中,每个名称都包含所有项。每一件商品都将按售出的数量排序。

+--------+------+-----+----+
|glasses |store1|  30 | 1  |
|glasses |store2|  35 | 2  |
|glasses |store3|  40 | 3  |
|shoes   |store2|  10 | 1  |
|shoes   |store1|  20 | 2  |
|shoes   |store3|  22 | 3  |
+--------+------+-----+----+

本文将介绍ROW_NUMBER()和DENSE_RANK()之间的有趣关系(RANK()函数没有特别处理)。当您需要在SELECT DISTINCT语句上生成ROW_NUMBER()时,ROW_NUMBER()将在被DISTINCT关键字删除之前生成不同的值。例如这个查询

SELECT DISTINCT
  v, 
  ROW_NUMBER() OVER (ORDER BY v) row_number
FROM t
ORDER BY v, row_number

... 可能会产生这种结果(DISTINCT没有影响):

+---+------------+
| V | ROW_NUMBER |
+---+------------+
| a |          1 |
| a |          2 |
| a |          3 |
| b |          4 |
| c |          5 |
| c |          6 |
| d |          7 |
| e |          8 |
+---+------------+

鉴于此查询:

SELECT DISTINCT
  v, 
  DENSE_RANK() OVER (ORDER BY v) row_number
FROM t
ORDER BY v, row_number

... 在这种情况下产生你可能想要的:

+---+------------+
| V | ROW_NUMBER |
+---+------------+
| a |          1 |
| b |          2 |
| c |          3 |
| d |          4 |
| e |          5 |
+---+------------+

注意,DENSE_RANK()函数的ORDER BY子句需要SELECT DISTINCT子句中的所有其他列才能正常工作。

这样做的原因是,从逻辑上讲,窗口函数是在应用DISTINCT之前计算的。

这三种功能的比较

使用PostgreSQL / Sybase / SQL标准语法(WINDOW子句):

SELECT
  v,
  ROW_NUMBER() OVER (window) row_number,
  RANK()       OVER (window) rank,
  DENSE_RANK() OVER (window) dense_rank
FROM t
WINDOW window AS (ORDER BY v)
ORDER BY v

... 你会得到:

+---+------------+------+------------+
| V | ROW_NUMBER | RANK | DENSE_RANK |
+---+------------+------+------------+
| a |          1 |    1 |          1 |
| a |          2 |    1 |          1 |
| a |          3 |    1 |          1 |
| b |          4 |    4 |          2 |
| c |          5 |    5 |          3 |
| c |          6 |    5 |          3 |
| d |          7 |    7 |          4 |
| e |          8 |    8 |          5 |
+---+------------+------+------------+

只有在分区中为特定排序值设置了关联时,才会看到差异。

在这种情况下,RANK和DENSE_RANK是确定的,对于排序列和分区列具有相同值的所有行最终将得到相同的结果,而ROW_NUMBER将任意(非确定地)将递增的结果分配给绑定的行。

示例:(所有行都有相同的StyleID,所以都在同一个分区中,在该分区中,前3行按ID排序时是绑定的)

WITH T(StyleID, ID)
     AS (SELECT 1,1 UNION ALL
         SELECT 1,1 UNION ALL
         SELECT 1,1 UNION ALL
         SELECT 1,2)
SELECT *,
       RANK() OVER(PARTITION BY StyleID ORDER BY ID)       AS [RANK],
       ROW_NUMBER() OVER(PARTITION BY StyleID ORDER BY ID) AS [ROW_NUMBER],
       DENSE_RANK() OVER(PARTITION BY StyleID ORDER BY ID) AS [DENSE_RANK]
FROM   T  

返回

StyleID     ID       RANK      ROW_NUMBER      DENSE_RANK
----------- -------- --------- --------------- ----------
1           1        1         1               1
1           1        1         2               1
1           1        1         3               1
1           2        4         4               2

您可以看到,对于三个相同的行,ROW_NUMBER增加,RANK值保持不变,然后跳到4。DENSE_RANK也将相同的秩赋给所有三行,但下一个不同的值被赋值为2。

看这个例子。

CREATE TABLE [dbo].#TestTable(
    [id] [int] NOT NULL,
    [create_date] [date] NOT NULL,
    [info1] [varchar](50) NOT NULL,
    [info2] [varchar](50) NOT NULL,
)

插入一些数据

INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (1, '1/1/09', 'Blue', 'Green')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (1, '1/2/09', 'Red', 'Yellow')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (1, '1/3/09', 'Orange', 'Purple')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (2, '1/1/09', 'Yellow', 'Blue')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (2, '1/5/09', 'Blue', 'Orange')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (3, '1/2/09', 'Green', 'Purple')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (3, '1/8/09', 'Red', 'Blue')

1重复相同的值

插入dbo。#TestTable (id, create_date, info1, info2) VALUES '1/1/09', '蓝色','绿色')

看所有

SELECT * FROM #TestTable

看看你的结果

SELECT Id,
    create_date,
    info1,
    info2,
    ROW_NUMBER() OVER (PARTITION BY Id ORDER BY create_date DESC) AS RowId,
    RANK() OVER(PARTITION BY Id ORDER BY create_date DESC)    AS [RANK]
FROM #TestTable

需要了解的不同