2015-02-09 10 views
0

填充與值的所有行空列我有這個表:如何從另一行

num | id | value1 | value2 | ..... | valueN 
____|____|________|________|_______|_______ 
1 | 1 | val1 | val2 | ..... | valN 
2 | 1 | blah | NULL | ..... | NULL 
1 | 2 | val12 | val22 | ..... | valN2 
2 | 2 | blah2 | NULL | ..... | NULL 

numid是一個主鍵。每個具有1 num的行都是填充所有列的行,對於該id(其中num高於1)的所有其他行都具有空列,我想用num = 1中的列填充相應的值,相同的id

我可以寫上所有num> 1行中運行,然後在運行空列,然後從num = 1行帶來了它,但有一個更SQLy辦法做到這一點的腳本?更一般的東西,沒有迭代每一列?

回答

1

那麼,你可以嘗試使用cross-table UPDATE JOIN

UPDATE mytbl AS a 
INNER JOIN (SELECT * FROM mytbl WHERE num = 1) AS b ON a.id = b.id 
SET a.value1 = b.value1, 
    a.value2 = b.value2, 
... 
    a.valueN = b.valueN 
WHERE a.num > 1 
1

要剛剛更新的值更新所有行(和維護他們,如果已經存在)的基本查詢應該是這樣的:

update Table1 t 
join (select * from Table1 where num = 1) ones 
on t.id = ones.id and t.num != ones.num 
set 
    t.value1 = IFNULL(t.value1, ones.value1), 
    t.value2 = IFNULL(t.value2, ones.value2), 
    t.valueN = IFNULL(t.valueN, ones.valueN); 

由於無法執行update tablea from tableb set a.* = b.*,因此您必須在查詢中包含要更新的所有列,並且如果我理解了您的問題,則這是您要避免的確切情況。

使用動態sql和查詢數據庫的信息模式,可以構建更新語句來更新所有列(手動排除的列除外)。這種方法有點冒失,但應該可以工作,但它可能表現不好,可能不安全。

給定一個名爲Table1一個測試表設置爲你的榜樣,你可以運行下面的代碼更新除了idnum所有列:

-- base update statement 
SET @sql:= 'update Table1 t 
join (select * from Table1 where num = 1) ones 
on t.id = ones.id and t.num != ones.num 
set '; 

-- concatenate the base update with the column specific part 
SELECT @stmnt := concat(@sql, group_concat(
    't.', 
    COLUMN_NAME, 
    ' = IFNULL(t.', 
    COLUMN_NAME,' 
    , ones.', 
    COLUMN_NAME, 
    ')')) 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE table_name = 'Table1' 
-- exclude these columns from the update 
AND column_name != 'id' 
AND column_name != 'num'; 

-- build a statement and execute it 
PREPARE dynamic_statement FROM @stmnt; 
EXECUTE dynamic_statement; 
DEALLOCATE PREPARE dynamic_statement;