按组sql server排名

时间:2015-01-21 13:06:49

标签: sql sql-server group-by rank partition

问题似乎很简单,但我无法理解它, 这是为sql server

 what I have in a table :            What I need as a output .
 cksum          id                      cksum       id
-2162514679     204                    -2162514679  204    1
-2162514679     207                    -2162514679  207    1
-2162514679     215                    -2162514679  215    1
-2162514679     218                    -2162514679  218    1
-2162514679     221                    -2162514679  221    1
-2160286363     257                    -2160286363  257    2
-2160286363     260                    -2160286363  260    2
-2160286363     332                    -2160286363  332    2
-2162514679     335                    -2162514679  335    3
-2162514679     338                    -2162514679  338    3
-2126731931     348                    -2126731931  348    4
-2126731931     387                    -2126731931  387    4

该表按id排序,我需要一个跟在id列之后的排名,但是对cksum进行分组,请注意cksum可以返回到先前的值但由于ID仍然具有其排名(这是值2162514679,它在开始时出现了5次,第二次出现了更多的轰鸣声,并且它们构成了两个不同的等级)。我已经使用了几个小时,看起来真的很愚蠢,就像使用带有分区的row_number或使用CTE但是没有...无法找到执行此操作的逻辑判断...任何人都有回答?

2 个答案:

答案 0 :(得分:3)

这有点棘手。你可以通过一个技巧获得ID的分组 - 行数的差异。然后,您需要获得每个组的最小ID,以确保最终排名顺序正确。那么你可以使用那么你可以使用密集等级:

select cksum, id, dense_rank() over (order by minid)
from (select t.*, min(id) over (partition by cksum, grp) as minid
      from (select t.*,
                   (row_number() over (order by id) -
                    row_number() over (partition by cksum order by id)
                   ) as grp
            from table t
           ) t
     ) t;

答案 1 :(得分:1)

这是一种不同的方法,它涉及模拟SQL Server 2008 R2中不可用的LAG窗口函数:

;WITH CTE_RN AS (
   SELECT cksum, id, ROW_NUMBER() OVER(ORDER BY id) AS rn
   FROM Checksums
), CTE_LAG AS (
   SELECT c1.cksum, c1.id, c1.rn,
          (CASE WHEN c2.cksum IS NULL OR c1.cksum = c2.cksum THEN 0
                ELSE 1
           END) AS flag 
   FROM CTE_RN AS c1
   LEFT JOIN CTE_RN AS c2 ON c1.rn = c2.rn+1
)
SELECT cksum, id,  (SELECT SUM(flag)
                    FROM CTE_LAG AS t2        
                    WHERE t2.rn <= t1.rn) + 1 AS [rank]     
FROM CTE_LAG AS t1

CTE_LAG返回以下结果集(基于OP的示例数据):

cksum       id  rn  flag
-------------------------
-2162514679 204 1   0
-2162514679 207 2   0
-2162514679 215 3   0
-2162514679 218 4   0
-2162514679 221 5   0
-2160286363 257 6   1
-2160286363 260 7   0
-2160286363 332 8   0
-2162514679 335 9   1
-2162514679 338 10  0
-2126731931 348 11  1
-2126731931 387 12  0

如果当前flag不等于之前的cksum,则字段cksum等于1,否则flag等于0。

字段rank只是flag的运行总计。