2013-02-11 106 views
2
UPDATE Houses 
SET lStatus = U.codesum 
FROM Houses H 
JOIN (SELECT ref, SUM(code) AS codesum 
    FROM Users 
    GROUP BY ref) AS U ON U.ref = H.ref 

上面的代碼獲取每個房屋(房屋表)的所有用戶。爲所有用戶彙總代碼列(用戶表)。最後更新房屋表的lstatus列中的結果。我的問題是: 我需要重寫不是總結代碼列的查詢。相反,我想創建案例陳述。例如:TSQL while循環

tempvar = 0 //local variable might be required 

For each user { 

If code == 1 then tempvar += 5 

else if code == 2 then tempvar += 10 

etc 

tempvar = 0; 
} 

一旦我們通過每個房屋的所有用戶,我們現在可以設置lStatus = tempvar。 然後tempvar應該重置爲0爲下一個房子。

+0

99%,如果你認爲在SQL Server中「循環」,你正在想錯誤的方式,並有一個更好,更高效,基於集合的答案。我不會像永遠/永遠不會說任何事情,但大多數情況下這是非常可靠的。 – 2013-02-11 16:31:31

+0

99.9%的時間有一種方法來獲得你想要的,而不循環或使用遊標。我知道人們在堆積着你,但這是一個扼殺萌芽的壞習慣。以下是使用UDF解決小型企業問題的另一個示例:http://granadacoder.wordpress.com/2008/07/24/cursors-setbased-and-scalar-udf/ – granadaCoder 2013-02-11 18:13:40

回答

5

編碼SQL時,應儘量避免循環和其他過程構造。關係數據庫不能輕易地優化這些事情,並且它們往往比其聲明式對應方式慢幾個數量級。在這種情況下,它似乎很簡單,以取代SUM(code)與你所描述的CASE聲明:

UPDATE Houses 
SET lStatus = U.codesum 
FROM Houses H 
JOIN (SELECT ref, SUM(CASE code WHEN 1 THEN 5 WHEN 2 THEN 10 ELSE 0 END) AS codesum 
    FROM Users 
    GROUP BY ref) AS U ON U.ref = H.ref 

這樣,SUM仍然可以處理你能想象你的臨時變量會做的義務。另外,如果你有很多情況,你可能會考慮把它們放在一張桌子上,然後簡單地加入,以獲得你的總和。這可能會更好地維護。我使用的是表變量在這裏,但它可能看起來如下:

DECLARE @codes TABLE (
    code INT NOT NULL PRIMARY KEY, 
    value INT NOT NULL 
) 
INSERT INTO @codes SELECT 1, 5 
INSERT INTO @codes SELECT 2, 10 

UPDATE Houses 
SET lStatus = U.codesum 
FROM Houses H 
JOIN (SELECT a.ref, SUM(b.value) AS codesum 
    FROM Users a 
    JOIN @codes b on a.code = b.code -- Here we get the values dynamically 
    GROUP BY a.ref) AS U ON U.ref = H.ref 
0

試試這個:

UPDATE Houses 
SET lStatus = U.codesum 
FROM Houses H 
JOIN (
      SELECT ref, SUM(
           CASE 
            WHEN Code = 1 
            THEN 5 
            WHEN Code = 2 
            THEN 10 
           END 
          ) AS codesum 
      FROM Users 
      GROUP BY ref 
     ) AS U ON U.ref = H.ref 
0

試試這個:時間

UPDATE Houses 
SET lStatus = U.code 
FROM Houses H 
JOIN (
      SELECT ref, SUM(
           CASE 
            WHEN Code = 1 
            THEN 5 
            WHEN Code = 2 
            THEN 10 
            ELSE 0 
           END 
          ) AS code 
      FROM Users 
      GROUP BY ref 
     ) AS U ON U.ref = H.ref