2012-01-30 30 views
1

我已經提出這個問題Grouping and update large database table,但我沒有得到答案。關於重複密鑰更新的SQL更新

我有一個表:name, date, detail, noname, date, detail一起作爲PK。

不知怎的,我需要更新detail,並有可能有重複的密鑰。因此我需要對no進行求和以得到重複的行。 ON DUPLICATE KEY UPDATE僅用於INSERT。那麼如何解決這個問題呢?

+0

你能澄清嗎?我假設有兩行'name = A,date = B,detail = C,no = 23'和'name = A,date = B,detail = D,no = 45' - 並且你想讓它變成所以如果你將第二行的細節更新爲C,那麼這兩行總和爲單行'name = A,date = B,detail = C,no = 68'?但是隻有在'name'和'date'字段也匹配的情況下呢? – 2012-01-30 23:11:52

+0

沒錯。它實際上是合併這些行。 – DrXCheng 2012-01-30 23:19:40

+0

從你的其他問題,雖然我猜這不是'只是'兩行...你打算改變*所有*細節領域更簡單(你不需要使用LIKE)和那麼所有的合併都會發生? – 2012-01-30 23:21:05

回答

0

糟糕的設計。你應該使用代理id主鍵,並使這些字段成爲一個複合唯一索引。如果你以後想引用這個表,你會得到什麼? 3個額外的字段作爲另一個表中的外鍵和額外的大索引。你將如何更新細節領域?如果你在它是一個大表之前說過它,這意味着PK索引重建。如果可能的話禁用約束,如果它沒有被引用。從源表中選擇不同或分組,並使用此選擇進行更新。第一

REPLACE INTO table(name,date,detail) 
    select distinct name,date,(select distinict detail from table) from 
    table 
+0

PK不會經常更新。我只想做一次性更新。 – DrXCheng 2012-01-30 23:12:31

+0

好的,你可以使用REPLACE。 http://dev.mysql.com/doc/refman/5.0/en/replace.html – 2012-01-30 23:17:31

+0

謝謝。你能舉一個這個案例的簡單例子嗎? – DrXCheng 2012-01-30 23:23:31

1

第一件事,是多列主鍵可能是一個壞主意;:


更換EDIT正如你發現的那樣,這使得操縱單個字段變得很困難。你應該做的是在該表中添加一個自動增量bigint列,該列將成爲你的新主鍵,而你的三列唯一性約束可以是一個唯一的索引。它應該表現得更好......但它也可以讓你做你需要的那種操作。它會讓你執行修改,但仍然可以讓你通過整數索引來識別原始行。

如果你這樣做,只要你不介意創建一些臨時表來處理,你的「一次性更新」現在可以安全地完成。事情是這樣的:

創建幾個具有相同的架構臨時表,但沒有獨特三列索引 - 你可以有一個非唯一索引,因爲它會幫助你瞭解查詢去表演;

將需要處理的記錄複製到第一個表中(包括唯一的整數主鍵);

更新您需要在臨時表中更新的所有detail列;

使用INSERT ... SELECTSUMGROUP BY將這些記錄合併到第二個表中;

INSERT INTO temp2 (...whatever...) SELECT ...whatever..., SUM(no) FROM temp1 GROUP BY ...whatever... 

最後,從原始表(使用整數主鍵)刪除temp1目錄表的所有記錄,並插入在TEMP2表中的記錄到原始表。

+1

多列主鍵不是一個壞主意,你爲什麼這麼認爲。 – 2012-01-31 01:08:38

+0

@ypercube我曾經喜歡在商業模式中使用任何「自然而然」獨特的東西作爲主鍵的想法;無論是字符串,還是多列的組合。它似乎比僅僅因爲添加數字PK更有意義。但是當你必須做出不可避免的改變時,它就會變得脆弱,就像OP現在正在做的那樣。 – 2012-01-31 01:25:03

+0

OP的問題是因爲他有多個具有相同的此鍵值(我們假設他希望它是唯一的或主要的)的行。一個簡單的「GROUP BY」將收集數據。 (將這些數據放在同一個表中,並刪除多行可能會非常棘手,是的。)我看不出代理鍵如何幫助。 – 2012-01-31 01:29:05