DENSE_RANK()查询

时间:2019-08-08 11:13:21

标签: sql tsql dense-rank

我有一些类似于下面的数据集...

ID        RowNumber
101       1
101       2
101       3
101       4
101       5
101       1
101       2

我想获得的是下面的另一列...

ID        RowNumber        New
101       1                1
101       2                1
101       3                1
101       4                1
101       5                1
101       1                2
101       2                2

我曾经玩过density_rank(),但是没有这种运气。

4 个答案:

答案 0 :(得分:1)

戈登已经提到过,您需要一列来指定数据顺序。如果我将ID按列排序,那么以下逻辑可以帮助您获得所需的结果-

WITH your_table(ID,RowNumber)
AS
(
SELECT 101,1 UNION ALL
SELECT 101,2 UNION ALL
SELECT 101,3 UNION ALL
SELECT 101,4 UNION ALL
SELECT 101,5 UNION ALL
SELECT 101,1 UNION ALL
SELECT 101,2
)

SELECT A.ID,A.RowNumber,
SUM(RN) OVER 
(
    ORDER BY ID
    ROWS BETWEEN UNBOUNDED  PRECEDING AND CURRENT ROW
) +1 New
FROM
(
    SELECT *, 
    CASE 
        WHEN LAG(RowNumber) OVER(ORDER BY ID) > RowNumber THEN 1 
        ELSE 0 
    END RN
    FROM your_table
)A

如果RowNumber中的值小于上一个,则上述将始终更改ROW NUMBER。另外,如果您希望在找到值1时更改行号,也可以实现相同的输出。这是静态选项-

SELECT A.ID,A.RowNumber,
SUM(RN) OVER 
(
    ORDER BY ID
    ROWS BETWEEN UNBOUNDED  PRECEDING AND CURRENT ROW
)  New
FROM(
    SELECT *, 
    CASE 
        WHEN RowNumber = 1 THEN 1 
        ELSE 0 
    END RN
    FROM your_table
)A 

输出为-

ID  RowNumber   New
101 1           1
101 2           1
101 3           1
101 4           1
101 5           1
101 1           2
101 2           2

答案 1 :(得分:0)

SQL表表示无序集。除非有列指定排序,否则没有排序。

假设您有这样的一列,则可以简单地通过计算直到每一点的“ 1”的数目来完成所需的操作:

select t.*,
       sum(case when rownumber = 1 then 1 else 0 end) over (partition by id order by <ordering column>) as new
from t;

答案 2 :(得分:0)

正如Gordon所暗示的那样,您的示例中没有默认顺序,因此很难想象如何获得确定性的结果(例如,提供给相同查询的相同值总是得出完全相同的答案)。

此示例数据包括一个顺序PK列,用于定义此集合的顺序

DECLARE @tbl TABLE (PK INT IDENTITY, ID INT, RowNumber INT)
INSERT @tbl(ID, RowNumber) VALUES (101,1),(101,2),(101,3),(101,4),(101,5),(101,1),(101,2);

SELECT t.* FROM @tbl AS t;

返回:

PK    ID     RowNumber
----- ------ -----------
1     101    1
2     101    2
3     101    3
4     101    4
5     101    5
6     101    1
7     101    2

此查询使用DENSE_RANK为您提供所需的信息:

DECLARE @tbl TABLE (PK INT IDENTITY, ID INT, RowNumber INT)
INSERT @tbl(ID, RowNumber) VALUES (101,1),(101,2),(101,3),(101,4),(101,5),(101,1),(101,2);

SELECT t.ID, t.RowNumber, New = DENSE_RANK() OVER (ORDER BY t.PK - RowNumber)
FROM @tbl AS t;

返回:

ID    RowNumber   New
----- ----------- ------
101   1           1
101   2           1
101   3           1
101   4           1
101   5           1
101   1           2
101   2           2

请注意,ORDER BY New不会影响计划。

答案 3 :(得分:0)

请尝试以下 将数据加载到临时表中

选择id,RowNumber,Row_number()over(按行号分区按ID排序)#temp新增 按Row_number()over排序(按RowNumber分区,按id排序),RowNumber