2012-08-27 18 views
1

我想在我管理的數據庫的表中重新分配一些值。mysql:使用重複主鍵添加整數值

Firstname(varchar), Lastname(varchar), Date(date), Icecream_consumed(int) 

其中Firstname,Lastname和Date的組合構成此表的主鍵。更改此表的結構不是一種選擇。

在數據庫中共有80個名字和姓氏的獨特組合,但我想將該數字降至5,並將總冰淇淋消耗量較小的一些記錄添加到總數最多的記錄中。因此,只有前5名的FirstName和LastName組合具有所有Icecream_consumed計數。

例如,如果我執行查詢:

SELECT Firstname, Lastname, SUM(Icecream_consumed) 
    FROM table_name 
GROUP BY Firstname, Lastname 
ORDER BY SUM(Icecream_consumed); 

我希望它只有5個結果,而不是80我怎樣才能修改表中的記錄來反映,而無需手動更新每個記錄?一個簡單的更新將不起作用,因爲它將插入具有相同主鍵的現有記錄存在的地方。

編輯:我注意到列ID是一種模糊。所以我從這個例子中刪除了它。

EDIT2:下面是一個例子:

現有:

名字,姓氏,SUM(Icecream_consumed)

John Doe 1500 
Joe Doe 1400 
Alex Foo 1111 
John Foo 1000 
Ben Foo 999 
Sue Cool 500 
Bill Smith 200 
Ben Smith 150 

我想改變表,以便總和(icecream_consumed )與sue,cool,bill smith和ben smith相關的值與john doe相關聯,因此只有5個結果可見。但是,如果我嘗試更新所有記錄,以便將sue cool改爲john doe,則會與主鍵發生衝突,因爲它們都可能具有相同日期的icecream_consumed值。 結果可能類似於:

John Doe 2000 
Joe Doe 1600 
Alex Foo 1261 
John Foo 1000 
Ben Foo 999 
+0

你想修改記錄(以獲得'SUM'更新)而不修改它們(保持相同的主鍵)?如果沒有,「當前」與「想要」的一個小例子將有助於更好地理解你想要達到的目標。 – alfasin

+0

聽起來像是一個'插入到x選擇......從...重複密鑰更新消耗=消耗+ y'的工作 –

+0

傑克你能以上面給出的例子的形式給出你的答案嗎?我正在研究「重複鍵」這個詞組,並且您提供的內容似乎會添加值,但我也需要消除較小的記錄,因此我們保持相同的總數並且不僅僅是從無處添加新的數字。 –

回答

2

工作SQL小提琴例如:http://sqlfiddle.com/#!2/0e8ab/1

因爲MySQL不能在UPDATE語句運行子選擇,如果再選擇相同表作爲一個在更新,你需要首先將數據暫時複製到另一個表中 - 所以當數據仍然進入數據庫時,請勿運行此操作,因爲它不是原子操作。您需要先關閉任何使用數據庫的應用程序。

-- Create a copy of the data 
CREATE TABLE table_name_copy SELECT * FROM table_name; 

-- Update the rows with the most Icecream_consumed to have the total 
UPDATE table_name t1 SET t1.Icecream_consumed = (
    SELECT SUM(t2.Icecream_consumed) 
    FROM table_name_copy t2 
    WHERE t2.Firstname = t1.FirstName AND t2.Lastname = t1.Lastname 
) 
WHERE id = (
    SELECT id 
    FROM table_name_copy t2 
    WHERE t2.Firstname = t1.FirstName AND t2.Lastname = t1.Lastname 
    ORDER BY Icecream_consumed DESC LIMIT 1 
); 

-- Delete the other rows that don't have the new totalled Icecream_consumed 
DELETE FROM table_name 
WHERE id != (
    SELECT t2.id 
    FROM table_name_copy t2 
    WHERE t2.Firstname = table_name.FirstName AND t2.Lastname = table_name.Lastname 
    ORDER BY Icecream_consumed DESC LIMIT 1 
); 

-- Remove the copied table 
DROP TABLE table_name_copy; 
+0

這是我沒有考慮過的一個選項,它很有意義,很好的工作。我現在想知道是否有辦法在不創建臨時表的情況下執行相同的操作。 –

+0

我唯一能想到的就是編寫一個小腳本或應用程序來完成數據遷移。但說實話,這可能是更多的工作。我已經修復了一些錯誤,並添加了一個工作示例,以此來顯示它的工作原理。 – theon