2017-12-22 15 views
2

Priorityint)という列に1からnの値を持つSQL Serverテーブルがあります。SQL Serverの新しい/古い値に基づいて他のレコードの優先度を更新します。

など。私はPriority列に以下の6つのレコードを持っている:私は2の6番目のレコードの優先順位を変更したい場合は

Col1 | Priority 
-----+---------- 
val1 | 1 
val2 | 2 
val3 | 3 
val4 | 4 
val5 | 5 
val6 | 6 

さて、その後、2の後のすべてのレコードの優先順位が1ずつ増加する必要がありますので出力は

Col1 | Priority 
-----+--------- 
val1 | 1 
val6 | 2 
val2 | 3 
val3 | 4 
val4 | 5 
val5 | 6 
だろう

T-SQLでこれを行うにはどうすればよいですか?

答えて

3

case表現使用:あなたはSQL Serverの2012+上にある場合は、CASE式またはIIF()を使用することができます

update tablename 
set Priority = case when Priority = 6 then 2 
        when Priority > 1 then Priority + 1 
        else Priority 
       end 
2

を:

CREATE TABLE P (
    Col1 VARCHAR(25), 
    Priority INT 
    ); 
INSERT INTO P VALUES 
('val1', 1), 
('val2', 2), 
('val3', 3), 
('val4', 4), 
('val5', 5), 
('val6', 6); 

UPDATE P 
SET Priority = IIF(Priority = 6, 2, IIF(Priority = 1, 1, Priority + 1)); 

SELECT * 
FROM P 
ORDER BY Priority; 

出力:

| Col1 | Priority | 
|------|----------| 
| val1 |  1 | 
| val6 |  2 | 
| val2 |  3 | 
| val3 |  4 | 
| val4 |  5 | 
| val5 |  6 | 
1

私は推測しますあなたは一般的なケースの答えをしたいと思います。 Y 6及び2) あなたは、あなたが優先順位6をインクリメントしてはならない、5と2を置き換えますたとえば場合...

DECLARE @PrioriyToChange int = 6; 
DECLARE @NewPrioriy int = 2; 
update PriorityTable set prioirity = 
       case when prioirity = @PrioriyToChange then @NewPrioriy 
        when prioirity between @NewPrioriy and @PrioriyToChange - 1 
          then prioirity + 1 
        else prioirity 
       end 
1

私は実際に異例の外に、Priorityfloatようにすることをお勧めしたいです状況によっては、既存の隣接値のペアの間にある新しいPriority値を常に計算することができます。

など。 val6を優先度1.5に設定した場合、他の行の値を変更する必要はありません。

時々(更新頻度に基づいて)ROW_NUMBER()を使用してテーブル全体を再構築して、値をintに戻すことができます。


など。リベースクエリ(優先度の値があまりにも偽りになった場合)は、次のようになります。

declare @t table (Val char(4), Priority float) 
insert into @t (Val,Priority) VALUES 
('val1',1), 
('val6',1.5), 
('val2',2) 

;With ForUpdate as (
    select *,ROW_NUMBER() OVER (ORDER BY Priority) as NewPri 
    from @t 
) 
UPDATE ForUpdate SET Priority = NewPri 
select * from @t 
関連する問題