我有一个使用sql Server 2008的表,它有一个带有两个可排序列的表,一个是手动设置的,另一个是通过系统过程计算的(此过程将所有内容整体排序,并从10开始分配排序,直到最高行次数10)
ID Manual System ------------------------ 1 null 300 2 2 380 3 null 500 4 null 200
我试图让它将id分类为4,2,1,3
我希望输出在应用时对系统进行手动排序.如果添加了另一行并且还需要考虑手动排序,则会使事情进一步复杂化.
ID Manual System ----------------------- 1 null 300 2 2 380 3 null 500 4 null 200 5 5 100
所以新的排序将是4,3,5
ID Manual System ----------------------- 4 null 200 2 2 380 1 null 300 3 null 200 5 5 100
有任何想法吗?我尝试过Rank,Dense_Rank,Row_Number等.
给出的解决方案似乎对我的例子是正确的.我忘了提到第三列personID也是这里的一个因素.
ID Manual System PersonID ------------------------------------- 4 null 200 22 2 2 380 22 1 null 300 22 3 null 200 22 5 5 100 22 8 1 210 25 6 1 480 25 7 null 600 25 9 4 800 25 10 null 990 25
所以我首先要按人员订购,然后通过手动排序,然后排序.这似乎仍然给我一个问题.
解决方法
这是我的解决方案:
http://sqlfiddle.com/#!3/a32a0/1/0
SELECT * FROM ( SELECT ID,ROW_NUMBER() OVER (PARTITION BY PersonID ORDER BY System)-.1 AS rn,Manual,System,PersonID FROM YourTable ) t0 ORDER BY PersonID,COALESCE(Manual,RN)
这是解释:
>我们将行号作为基本行号.但是因为我们首先按照PersonID的高阶索引进行排序,所以我在ORDER BY之前进行PARTITION BY ……这会重置每个MANUAL分组的索引
>如果ROW_NUMBER的自然顺序与MANUAL排序之间存在联系,则减去.1((0,1)之间的任意数量).在平局的情况下,这优先考虑MANUAL值
>在排序最终结果时,我首先按PARTITION BY值排序,首先确保正确的分组,然后按MANUAL和RN的第一个非空值排序
试试看.指出前两个答案的起点.我用其中一个作为起点,然后从那里重写.
编辑:删除了.1的减法并添加了一个新的排名函数,它“优化”优化器,使其优先于手动排名.我不知道在所有情况下这是否成立,或者优化器是否会在其他情况下无法按此顺序给出结果,但我想包括这些结果以防它们有用.
我更新的查询如下:
SELECT * FROM ( SELECT ID,ROW_NUMBER() OVER (PARTITION BY PersonID ORDER BY System) AS rn,ROW_NUMBER() OVER (PARTITION BY PersonID ORDER BY Manual) AS rn_throwaway,PersonID FROM YourTable ) t0 ORDER BY PersonID,RN)
其使用的例子是http://sqlfiddle.com/#!3/1831d/55/0和http://sqlfiddle.com/#!3/a32a0/9/0