SQL按“重量”排序记录

时间:2011-10-28 09:16:34

标签: sql tsql sql-server-2008

我们有一个系统,可以通过表中的“优先级”编号处理记录。我们通过表格的内容来定义优先级,例如

UPDATE table
SET priority=3
WHERE processed IS NULL

UPDATE table
SET priority=2
WHERE balance>50

UPDATE table
SET priority=1
WHERE value='blah'

(请忽略优先级之间可能存在'重叠'的事实:))

这很好 - 表按优先级顺序处理,因此首先处理“value”列为“blah”的所有行。

我被赋予了添加选项的任务,以通过可定义的“权重”来订购记录。例如,我们希望50%的处理优先级为1,优先级为25%,优先级为25%,优先级为25%。因此,根据上述情况,在每100条记录中,其中50条将是“值”为“blah”的记录。 “,其中25个将是”平衡“大于50等。

我正在试图弄清楚如何做到这一点:“优先级”的某种加权递增值似乎是最好的方法,但我无法理解如何对此进行编码。有人可以帮忙吗?

编辑:道歉,应该说:这是在MSSQL 2008上运行

2 个答案:

答案 0 :(得分:5)

一般的想法是将任务收集到桶中,划分为整数的边界:

select
  task_id
from (  
  select 
    task_id, 
    ((task_priority_order - 1) / task_priority_density) as task_processing_order
  from (
    select
      t.task_id                                            as task_id, 
      t.priority                                           as task_priority, 
      row_number() 
        over (partition by t.priority order by t.priority) as task_priority_order,
      case
        when t.priority = 3 then 50
        when t.priority = 2 then 25
        when t.priority = 1 then 25
      end                                                  as task_priority_density
    from
      table t
  )
)
order by task_processing_order

在从0.0到0的音调中。(9)我们从前50个优先级为3的记录构建了100条记录,前25条记录优先级为2,前25条记录优先级为1.

从1.0到1的下一个调教。(9)表示下一批记录。

如果没有更多具有某些优先级值的任务,则剩余的任务将以相同的比例放入存储桶中。例如。如果没有足够的优先级为3的任务,那么剩下的任务将以50/50的比例安排。

task_id - 用于任务识别的一些代理键。

P.S。抱歉,我现在无法测试此查询,因此任何语法修正都非常感谢。

更新:根据评论更正了查询语法。

答案 1 :(得分:0)

给定测试脚本提供以下输出。如果你要对最终结果应该制定一些规则,我愿意再看看它。

<强>结果

Priority    Processed       Balance Value
3           NULL            NULL    NULL
NULL        0               49      NULL
NULL        1               49      NULL
NULL        0               50      NULL
NULL        1               50      NULL
2           0               51      NULL
2           1               51      NULL
2           0               51      Notblah
1           1               51      blah

测试脚本

DECLARE @Table TABLE (Priority INTEGER, Processed BIT, Balance INTEGER, Value VARCHAR(32))

INSERT INTO @Table VALUES 
  (NULL, NULL, NULL, NULL)
  , (NULL, 0, 49, NULL)
  , (NULL, 1, 49, NULL)
  , (NULL, 0, 50, NULL)
  , (NULL, 1, 50, NULL)
  , (NULL, 0, 51, NULL)
  , (NULL, 1, 51, NULL)
  , (NULL, 0, 51, 'Notblah')
  , (NULL, 1, 51, 'blah')

UPDATE @table SET priority=3 WHERE processed IS NULL
UPDATE @table SET priority=2 WHERE balance > 50
UPDATE @table SET priority=1 WHERE value = 'blah'

SELECT  *
FROM    @table