2014-03-12 59 views
0

我有表InfoID, tName, restNameisOpen列。如何交換連續兩列的值? SQL Server

而且我有這樣的價值觀,例如:

ID (Unique) | tName | restName | isOpen 
-----------------------------------------  
9   - TN10 - RN10 - 0 
10   - TN10 - RN10 - 1 
11   - TN11 - RN11 - 1 

我想去的地方isOpen=1交換tNamerestName值。

ID (Unique) | tName | restName | isOpen 
----------------------------------------  
9   - TN10 - RN10 - 0 
10   - TN11 - RN11 - 1 
11   - TN10 - RN10 - 1 

我知道我應該查詢之前更改值,我的意思是我知道tName-restName應該改變什麼tName-restName

我是非常新的查詢,我只是無法弄清楚如何交換值。如果它是像C這樣的語言,我只需要使用一個臨時值並交換它們。可以用1個查詢完成嗎?我看到交換列時很容易,但是我找不到適合自己情況的任何有用材料。

UPDATE

我忘了告訴我不知道ID的當時的值,不希望與另一個查詢來獲取它們。

我要讓像「交換值,其中restName=RN10tName=TN10restName=RN11tName=TN11isOpen=1」如果有可能的查詢。所以選擇大約是tNamerestNameisOpen我猜。

謝謝您的回覆,

有一個愉快的一天

+0

你只是想在這個問題與IDS 10和11或所示的兩行做到這一點更大的數字?如果更大的數字是選擇一對行的邏輯是什麼? –

+0

謝謝你的回答。我更新了我的問題,以便更清楚。 – Sezertt

回答

0

我寫了一個查詢長時間後嘗試:)做了我想要的完全,但我不能確定它是否完全是真的。如果有人可以檢查並告訴,我會很高興。謝謝...

UPDATE Info 
SET tName = CASE tName 
WHEN @tNameOld THEN @tNameNew 
WHEN @tNameNew THEN @tNameOld 
END,  
restName = CASE restName 
WHEN @restNameOld THEN @restNameNew 
WHEN @restNameNew THEN @restNameOld 
END  
WHERE tName in (@tNameOld,@tNameNew)  
AND isOpen=1  
AND restName in (@restNameOld,@restNameNew) 
+0

這將對一行進行交換,例如,它匹配舊值,但不一定要確認也會有一行,同時具有isOpen等於1的新值。它也可能創建錯誤匹配比如,一行有舊的'tName'和新的'restNew'值。這些都可能在您的數據中無關緊要,但在我的解決方案中我很小心避免這種情況。 –

+0

非常感謝。我能再問一個問題嗎? 如果同一個tName和restName只有一個'isOpen = 1'語句會怎麼樣?那麼可以使用這個權利? – Sezertt

2

對於一個更通用互換,讓我們說我們有這個:

declare @Swaps table (
    tFirst varchar(10) not null, 
    rFirst varchar(10) not null, 
    tSecond varchar(10) not null, 
    rSecond varchar(10) not null 
) 
INSERT INTO @Swaps (tFirst,rFirst,tSecond,rSecond) VALUES 
        ('TN10','RN10','TN11','RN11') 
       --And more rows 
UPDATE i 
SET tName = o.tName, 
    restName = o.restName 
FROM @Swaps s 
    inner join 
    Info i 
     on 
      ((s.tFirst = i.tName and s.rFirst = i.restName) or 
      (s.tSecond = i.tName and s.rSecond = i.restName)) and 
      i.IsOpen = 1 
    inner join 
    Info o 
     on 
      ((s.tFirst = o.tName and s.rFirst = o.restName) or 
      (s.tSecond = o.tName and s.rSecond = o.restName)) and 
      o.IsOpen = 1 and 
      (i.tName <> o.tName or i.restName <> o.restName) 

早些時候回答

對於此特定交換,它可以是d一個爲:

UPDATE i 
SET tName = o.tName 
    restName = o.restName 
FROM Info i 
INNER JOIN Info o 
on (
    (i.ID = 10 and o.ID = 11) or 
    (i.ID = 11 and o.ID = 10) 
) 

但我不確定您的實際問題大小有多大。如果有很多交換,您可能想要將所有這些組合存儲在另一個(臨時)表中,並進一步加入。

+0

謝謝你的回答。我更新了我的問題,以便更清楚。關於你的答案我沒有具體的ID,我需要檢查isOpen,只是試着舉一個例子說明我將如何處理表格。 – Sezertt

0

試試這個:

設置

CREATE TABLE #Info 
(
    ID INT Primary Key NOT NULL, 
    tName Varchar(50) NOT NULL, 
    restName VARCHAR(50)NOT NULL, 
    isOpen bit NOT NULL 

) 

INSERT INTO #Info VALUES 
      (9, 'TN10', 'RN10', 0), 
    (10, 'TN10','RN10', 1), 
    (11, 'TN11','RN11', 1) 

select * 
from #Info 


UPDATE #info 
    SET tName = newTName, 
     restName = newRestName 
FROM #info i 
INNER JOIN 
    (
     select id, tName newRestName, restName newTName 
     from #Info 
     WHERE isOpen = 1 
    ) i2 
ON i.ID = i2.ID 

SELECT * 
FROM #Info