更新语句以重新排序表队列

时间:2012-12-28 02:48:21

标签: sql sql-server-2008 tsql

有一个包含以下测试数据的表

PKId         EqId    Worker     Queue
1             1      Worker1      1
3             1      Worker3      3
2             1      Worker2      4
4             1      Worker4      7 

需要更新将旋转Workers的表,以便在update语句之后数据将如下所示

PKId         EqId   Worker  Queue
1             1     Worker1   7
3             1     Worker3   1
2             1     Worker2   3
4             1     Worker4   4 

2 个答案:

答案 0 :(得分:2)

您几乎可以通过加入来执行此操作:

select pkid, eqid, worker, queue, tprev.queue as newqueue
from t left outer join
     t tprev
     on t.pkid = tprev.pkid + 1

但是,对于PkID = 1,最终会得到NULL。因此,我们需要将其添加到:

select pkid, eqid, worker, queue, coalesce(tprev.queue, lastone.queue) as newqueue
from t left outer join
     t tprev
     on t.pkid = tprev.pkid + 1 cross join
     (select top 1 queue from t order by pkid desc) as lastone

如果您确实想要更新,那么我们可以将其放在更新声明中:

update t
    set queue = newqueue
    from (select pkid, eqid, worker, queue,
                 coalesce(tprev.queue, lastone.queue) as newqueue
          from t left outer join
               t tprev
               on t.pkid = tprev.pkid + 1 cross join
               (select top 1 queue from t order by pkid desc) as lastone
         ) newt
    where t.pkid = newt.pkid

我意识到您的主键可能有漏洞。在这种情况下,请从以下查询开始:

select t.*, newQueue
from (select t.*,
             (select top 1 queue from t t2 where t2.pkid < t.pkid order by t2.pkid desc
             ) as newQueue
      from t
     ) t

在更新声明中:

update t
    set queue = newqueue
    from (select pkid, eqid, worker, queue,
                 coalesce(Newqueue, lastone.queue) as newqueue
          from (select t.*,
                       (select top 1 queue from t t2 where t2.pkid < t.pkid order by t2.pkid desc
                       ) as newQueue
                from t
               ) t cross join
               (select top 1 queue from t order by pkid desc) as lastone
        ) newt
    where t.pkid = newt.pkid

答案 1 :(得分:0)

尝试:

DECLARE @q TABLE (
  PKId INT, 
  EqID INT, 
  Worker VARCHAR(50), 
  [Queue] INT
) 

INSERT @q 
SELECT 1,1,'Worker1', 1 UNION ALL
SELECT 3,1,'Worker3', 3 UNION ALL 
SELECT 2,1,'Worker2', 4 UNION ALL 
SELECT 4,1,'Worker4', 7 

;WITH t AS (
SELECT
  PKId,
  [Queue],
  ROW_NUMBER() OVER (ORDER BY [Queue]) AS rn
FROM @q 
)
UPDATE q 
SET [Queue] = q2.NewQueue
FROM @q q 
JOIN ( 
  SELECT
    t1.PKId,
    COALESCE(t2.[Queue], 
      (SELECT TOP 1 [Queue] FROM t ORDER BY [Queue] DESC)) AS NewQueue
  FROM t t1
  LEFT JOIN t t2
  ON t1.rn = t2.rn + 1
) q2 
  ON q.PKId = q2.PKId