2011-06-17 27 views
3

我正在SQL Server 2008 R2中進行數據遷移。我是SQL-Server noob,但我很瞭解Ingres和MySql。SQL Server:UPDATE語句,其中MAX查詢

我需要將兩個新字段的「默認值」設置爲另一個表中的「當前值」。這是我第一次天真的嘗試(我將如何在Ingres做到這一點)。

update rk_risk 
set  n_target_probability_ID = a.n_probability_ID 
     , n_target_consequence_ID = a.n_consequence_ID 
from rk_assess a 
WHERE a.n_assess_id = (
    SELECT MAX(n_assess_id) 
    FROM rk_assess a2 
    WHERE a2.n_risk_id = a.n_risk_id 
); 

上面的查詢執行沒有在續集中的錯誤,不過這臺ALL的n_target_probability_ID的& n_target_consequence_ID的到相同的值 ...的奪標最後一次評估(如並列爲「最後評估這個風險「)。

rk_assess表中包含的評估記錄的完整歷史rk_risk秒,我的使命是「默認」的新目標概率&後果的風險表中的值列從「當前」(即最後一個)評估記錄。 rk_assess.n_assess_id列是一個自動遞增的標識符(一次設置不變),所以max-id應該是最後輸入的記錄。

我已經有一個搜索,無論是在谷歌和SO,並嘗試了幾個不同版本的查詢,但我仍然堅持。這裏有一些其他的史詩般的失敗,並帶有參考。

update rk_risk 
set  n_target_probability_ID = (select a.n_probability_ID from rk_assess a where a.n_assess_id = (select max(n_assess_id) from rk_assess a2 where a2.n_risk_id = a.n_risk_id) as ca) 
     , n_target_consequence_ID = (select a.n_consequence_ID from rk_assess a where a.n_assess_id = (select max(n_assess_id) from rk_assess a2 where a2.n_risk_id = a.n_risk_id) as ca) 
; 

http://stackoverflow.com/questions/6256844/sql-server-update-from-select 

update r 
set  r.n_target_probability_ID = ca.n_probability_ID 
     , r.n_target_consequence_ID = ca.n_consequence_ID 
from rk_risk r 
join rk_assess a 
on  a.n_risk_id = r.n_risk_id 

select r.n_risk_id 
      , r.n_target_probability_ID, r.n_target_consequence_ID 
      , ca.n_probability_ID, ca.n_consequence_ID 
from rk_risk r 
join rk_assess a 
on  a.n_risk_id = r.n_risk_id 

http://stackoverflow.com/questions/4024489/sql-server-max-statement-returns-multiple-results 

UPDATE rk_risk 
SET  n_target_probability_ID = ca.n_probability_ID 
     , n_target_consequence_ID = ca.n_consequence_ID 
FROM (rk_assess a 
INNER JOIN (
     SELECT MAX(a2.n_assess_id) 
     FROM rk_assess a2 
     WHERE a2.n_risk_id = a.n_risk_id 
) ca -- current assessment 

任何指針將不勝感激。提前謝謝大家,甚至可以閱讀這些。

乾杯。基思。

+0

是否必須在一個聲明中完成? – WOPR 2011-06-17 04:42:30

回答

6

如何:

update rk_risk 
set  n_target_probability_ID = a.n_probability_ID 
     , n_target_consequence_ID = a.n_consequence_ID 
from rk_assess a 
JOIN (
    SELECT n_risk_id, MAX(n_assess_id) max_n_assess_id 
    FROM rk_assess 
    GROUP BY n_risk_id 
    ) b 
ON a.n_risk_id = b.n_risk_id AND a.n_assess_id = b.max_n_assess_id 
WHERE a.n_risk_id = rk_risk.n_risk_id 
+0

評估加入到「父」rk_risk上'rk_assess.n_risk_id' – corlettk 2011-06-17 04:57:17

+0

@corlettk - 嘗試上面的更新,我相信這將工作。關鍵是你需要一個派生表(b),它返回給你每個n_risk_id的最後評估結果,然後你可以在PK上加入rk_assess來獲得相關數據。合理? – 2011-06-17 05:01:45

+0

我嘗試過你的拳頭剪裁,它的行爲與我第一次嘗試時相同......即所有行都從abolutute-last評估中獲得了值......我嘗試了修改後的版本,並且** IT WORKS ** !!!謝謝soooooo了。我一直非常沮喪,我認爲這很容易,因此沒有估計任何時間,結果變得如此棘手。再次感謝。基思。 – corlettk 2011-06-17 05:14:34

1

我所以只是今天發現了這個來自另外一個問題。 UPDATE-FROM構造不是標準SQL,MySQL的非標準版本與Postgres的非標準版本不同。從這裏的問題看來,SQL Server遵循Postgres。

Jerad在他的編輯中指出,問題是在被更新的表和子查詢中的表之間沒有關聯。 MySQL似乎在這裏創建了一些隱式聯接(在另一個SO例子中的列名稱上,它是通過將同一個表的兩個副本視爲相同的,而不是單獨的)。

我不知道,如果SQL Server允許在子查詢窗口,但如果這樣做,我想你想

UPDATE rk_risk 
set  n_target_probability_ID = a.n_probability_ID 
     , n_target_consequence_ID = a.n_consequence_ID 
from 
    (SELECT * FROM 
    (SELECT n_risk_id, n_probability_ID, n_consequence_ID, 
       row_number() OVER (PARTITION BY n_risk_id ORDER BY n_assess_ID DESC) AS rn 
     FROM rk_assess) 
    WHERE rn = 1) AS a 
WHERE a.n_risk_id=rk_risk.n_risk_id; 
+0

謝謝!這是Conrads第一個解決方案的另一個變種。我以爲我知道SQL,但我很快意識到我有很多東西需要學習。 – corlettk 2011-06-17 05:27:02

+0

@CorlettK:我剛剛開始使用窗口和CTE。我認爲他們沒有得到足夠的關注,因爲MySQL不支持它們。 – 2011-06-17 05:36:42

3

如果你使用SQL 2005或更高版本,您可以除了Jerad的答案使用ROW_NUMBER函數

With b 
(
     SELECT n_risk_id, 
       n_assess_id, 
       n_probability_ID, 
       n_consequence_ID, 
       row_number() over (partition by n_risk_id order by n_assess_id desc) row 
     FROM rk_assess 
) 
update rk_risk 
set  n_target_probability_ID = b.n_probability_ID 
     , n_target_consequence_ID = b.n_consequence_ID 
from b 
WHERE a.n_risk_id = rk_risk.n_assess_id 
     and row =1 

或者CROSS JOIN

update rk_risk 
set  n_target_probability_ID = b.n_probability_ID 
     , n_target_consequence_ID = b.n_consequence_ID 
from rh_risk r 
     CROSS JOIN 
     (
     SELECT TOP 1 
       n_risk_id, 
       n_assess_id, 
       n_probability_ID, 
       n_consequence_ID 
     FROM rk_assess 
     order by n_assess_id desc 
     WHERE a.n_risk_id = r.n_assess_id) b 
+0

我喜歡那第二個版本...使用「從順序中選擇第一個」總是對我來說比「x = max(x)where rest-of-where-clause」對我更「自然」......這是在「order by」子句中有(邏輯上)幾個字段時非常麻煩。 – corlettk 2011-06-17 05:20:43

2

我想這一點,看起來是幹活g:

update rk_risk 
set  n_target_probability_ID = a.n_probability_ID, 
     n_target_consequence_ID = a.n_consequence_ID 
from rk_assess a, rk_risk r 
WHERE a.n_risk_id = r.n_risk_id 
and a.n_assess_id in (select MAX(n_assess_id) from rk_assess group by n_risk_id) 
+1

謝謝你改進格式 – 2011-06-17 05:27:02

+1

謝謝你回答...這是一個團隊的事情;-) – corlettk 2011-06-18 08:08:27