2017-01-28 55 views
0

代碼:更新列與第二最高數字在SQL

update [MemberBackup].[dbo].[uid3times$] 
set rc2tobedeleted = 
case when rc1 > rc2 and rc1 > rc3 and rc2 < rc3 then rc2 
when rc2 > rc3 and rc2 > rc1 and rc1 < rc3 then rc1 
when rc3 > rc1 and rc3 > rc2 and rc1 < rc2 then rc1 
else 0 end 

我有3列RC1,RC2,RC3和號碼3列是隨機我想更新/設置在第二次數最多rc2tobedeleted

但我的代碼來到其他地方,因爲我認爲我已經照顧了3種可能的情況。

我在做什麼錯了?

回答

2

Giorgos答案是偉大的,但它可以簡化像這樣Sql server 2012及以上

UPDATE [MemberBackup].[dbo].[uid3times$] 
SET rc2tobedeleted = (SELECT rc 
         FROM (VALUES (rc1),(rc2),(rc3)) tc (rc) 
         ORDER BY rc DESC 
         OFFSET 1 ROWS FETCH next 1 rows only) 

舊版本下面是使用這個

UPDATE [MemberBackup].[dbo].[uid3times$] 
SET rc2tobedeleted = (SELECT rc 
         FROM (SELECT Row_number()OVER(ORDER BY rc DESC) rn,rc 
           FROM (VALUES (rc1),(rc2),(rc3)) tc (rc)) a 
         WHERE rn = 2) 

理念,unpivoting的三列到單個列並在未轉義的行上生成行號並更新具有行號的記錄2

Ano這種方法的好處是甚至你有三個以上的三列,你想找到第n個記錄,那麼它比笨拙更容易和優雅CASE陳述

+0

如果他們是4值而不是3呢? –

+0

@ArijitMukherjee - 簡單的將第四列添加到表值構造函數。像這樣((VALUES(rc1),(rc2),(rc3),(rc4))' –

+0

,如果我想要第三高,那麼rn = 3或偏移2正確? –

4

試試這個:

;WITH ToUpdate AS (
    SELECT rc2tobedeleted, t.v AS val 
    FROM [MemberBackup].[dbo].[uid3times$] 
    CROSS APPLY (
     SELECT x.v 
     FROM (VALUES (rc1), (rc2), (rc3)) AS x(v) 
     ORDER BY x.v DESC 
     OFFSET 1 ROWS 
     FETCH NEXT 1 ROWS ONLY) AS t 
UPDATE ToUpdate 
SET rc2tobedeleted = val 

我覺得上面的查詢在比較更清潔和易於理解的結構,多一個CASE表達WHEN條款。

查詢使用VALUES表值構造函數以構建一個由字段值rc1, rc2, rc3組成的內聯表。使用從SQL Server 2012開始提供的OFFSET FETCH子句,我們可以獲得第二高的值。

最後,使用CTE執行UPDATE操作:將更新從CTE傳播到存儲在數據庫中的實際表的底層行。

+1

非常優雅! +1! – Mureinik

+0

如果它們是4值而不是3呢? –