SQL重新排序优先级逐行

时间:2009-11-09 15:01:43

标签: sql sql-server-2005

我上周发布了这个问题的早期版本,但经过进一步考虑后,我意识到情况比最初描述的要复杂一点,我可以使用一些进一步的帮助:

我的SQL表有3个影响我的问题的字段:“Priority”为真,Start_Date为datetime,Furnace_Name为varchar(10)。当用户向表中添加项目时(通过VB.net Windows应用程序),他指定了给定Start_Date的优先级。

如果Item1在指定的熔炉中为优先级1 ,则同一熔炉中的Item2 可能为优先级2,并且在第1项之后将给予Start_Date。 / p>

但是如果Item2的优先级为0.5(或任何小于Item1优先级的数字),则其Start_Date将在Item1的Start_Date之前。注意:用户可以指定一个例如3.75的prioirty,或者他们想要的任何数字。由于业务规则,PR 0.5的作业可以推进并在同一个炉子中具有更高优先级的作业之后结束。

添加每个项目后,我想浏览项目列表并更新所有优先级,使它们是整数,从最早的Start_Date开始,优先级= 1,然后是2,3,等等。但是我第一次发布这个问题时,我忽略了在每个熔炉内重复编号优先级,因此每个熔炉可能都有一个Prioirty 1,2等等。

此外,指定的熔炉可能具有1:n具有相同优先级的项目。在将这些优先级重新编号为整数后,以相同优先级开头的项目仍应具有相同的优先级。

读者建议:

Update Table 
Set Priority = 
    (Select Count(*) 
     From table
     Where Start_Date <= T.Start_Date)   
     From Table T   
Where Start_Date > getDate()

我将其增强为:

Update tblTable
Set      Priority = 
 (Select Count(*) 
 From tblTable
 Where Start_Date <= T.Start_Date and
 Start_Date  >= @CutoffDate 
 and Furnace_Name = T.Furnace_Name
 )   
From tblTable T

但这并不是很有效,因为炉内的优先权不是从1开始的。有人可以向我澄清这样做或解决问题的最佳方法吗?

以下是一些测试数据:

Sch_ID Furnace重新订购后的Start_Date优先级所需优先级 372 1335 11/9/09 8:00 AM 1 1 380 1335 11/9/09 7:00 AM 1 1 314 1335 11/9/09 10:30 AM 2 2 324 1335 11/9/09 10:00 AM 2 2 235 1335 11/9/09 4:00 PM 0.5 3 234 1335 11/9/09 4:00 PM 0.5 3

403 1510 11/9/09 11:30 AM 2 2 404 1510 11/9/09 11:30 AM 2 2 402 1510 11/9/09 8:30 AM 2 2 389 1510 11/9/09 7:30 AM 1 1 390 1510 11/9/09 7:30 AM 1 1 388 1510 11/9/09 7:00 AM 1 1 374 1510 11/9/09 6:30 PM 3.5 4 383 1510 11/9/09 5:30 PM 3.5 4 385 1510 11/9/09 3:30 PM 3 3 386 1510 11/9/09 1:30 PM 3 3

谢谢。

P.S。

我首先需要重新编写作业优先级的原因是,在应用了与调度作业相关的业务规则之后,它们的优先级可能(尽管不常见)超出数字顺序。例如,在不同炉子中存在欺骗可以将当前作业的开始时间推回到时间,迫使它在当天晚些时候比具有更高PR数量的作业(因此具有更低优先级)。

由于用户通过指定PR来指示作业在炉中的相对重要性,因此必须在添加每个作业后重新编号优先级。上面描述的情况下,PR 2的工作位于2个PR 1的工作之间,但是不会发生2个或更多优先级相同的工作。

感谢您提供的帮助。你能把它作为最后一步吗?

谢谢。

3 个答案:

答案 0 :(得分:2)

WITH    rows AS
        (
        SELECT  tt.*, DENSE_RANK() OVER (PARTITION BY Furnace_Name ORDER BY Priority) AS dr
        FROM    tblTable tt
        )
UPDATE  rows
SET     Priority = dr

更新2:

试试这个:

WITH    data (Sch_ID, Furnace, Start_Date, Priority, Pr) AS
        (
        SELECT 372, 1335, CAST('11/9/09 8:00 AM' AS DATETIME), 1, 1
        UNION ALL
        SELECT 380, 1335, '11/9/09 7:00 AM', 1, 1
        UNION ALL
        SELECT 314, 1335, '11/9/09 10:30 AM', 2, 2
        UNION ALL
        SELECT 324, 1335, '11/9/09 10:00 AM', 2, 2
        UNION ALL
        SELECT 235, 1335, '11/9/09 4:00 PM', 0.5, 3
        UNION ALL
        SELECT 234, 1335, '11/9/09 4:00 PM', 0.5, 3
        UNION ALL
        SELECT 403, 1510, '11/9/09 11:30 AM', 2, 2
        UNION ALL
        SELECT 404, 1510, '11/9/09 11:30 AM', 2, 2
        UNION ALL
        SELECT 402, 1510, '11/9/09 8:30 AM', 2, 2
        UNION ALL
        SELECT 389, 1510, '11/9/09 7:30 AM', 1, 1
        UNION ALL
        SELECT 390, 1510, '11/9/09 7:30 AM', 1, 1
        UNION ALL
        SELECT 388, 1510, '11/9/09 7:00 AM', 1, 1
        UNION ALL
        SELECT 374, 1510, '11/9/09 6:30 PM', 3.5, 4
        UNION ALL
        SELECT 383, 1510, '11/9/09 5:30 PM', 3.5, 4
        UNION ALL
        SELECT 385, 1510, '11/9/09 3:30 PM', 3, 3
        UNION ALL
        SELECT 386, 1510, '11/9/09 1:30 PM', 3, 3
        ),
        ranks AS
        (
        SELECT  *, DENSE_RANK() OVER (PARTITION BY Furnace ORDER BY CASE WHEN Priority = 0.5 THEN 1 ELSE 0 END, Priority) AS Dr
        FROM    data
        )
SELECT  *
FROM    Ranks
ORDER BY
        Furnace, Start_Date

这取决于原始优先级的排序方式与StartDate s相同。

如果不是,你应该决定会发生什么。说,这些数据将如何订购?

Date   Priority 
07:00  1
08:00  2
09:00  1
10:00  2

答案 1 :(得分:2)

在我看来,这里的主要问题是底层模型,这使得这很复杂。如果你考虑改变模型,你的大多数问题都会消失,例如:

furnace_model_01 我知道这不是你所要求的,但从长远来看......

评论后更新
这个应该使您能够指定谁安排了什么,何时何地。

furnace_model_02

答案 2 :(得分:1)

我认为让一个由用户和应用程序/数据库的半自动算法设置的字段听起来是个坏主意。您是否只能在表Start_Date时根据Priorityselect订购?