我已经提出这个问题Grouping and update large database table,但我没有得到答案。关于重复密钥更新的SQL更新
我有一个表:name, date, detail, no
和name, date, detail
一起作为PK。
不知怎的,我需要更新detail
,并有可能有重复的密钥。因此我需要对no
进行求和以得到重复的行。 ON DUPLICATE KEY UPDATE
仅用于INSERT
。那么如何解决这个问题呢?
我已经提出这个问题Grouping and update large database table,但我没有得到答案。关于重复密钥更新的SQL更新
我有一个表:name, date, detail, no
和name, date, detail
一起作为PK。
不知怎的,我需要更新detail
,并有可能有重复的密钥。因此我需要对no
进行求和以得到重复的行。 ON DUPLICATE KEY UPDATE
仅用于INSERT
。那么如何解决这个问题呢?
糟糕的设计。你应该使用代理id主键,并使这些字段成为一个复合唯一索引。如果你以后想引用这个表,你会得到什么? 3个额外的字段作为另一个表中的外键和额外的大索引。你将如何更新细节领域?如果你在它是一个大表之前说过它,这意味着PK索引重建。如果可能的话禁用约束,如果它没有被引用。从源表中选择不同或分组,并使用此选择进行更新。第一
REPLACE INTO table(name,date,detail)
select distinct name,date,(select distinict detail from table) from
table
第一件事,是多列主键可能是一个坏主意;:
更换EDIT正如你发现的那样,这使得操纵单个字段变得很困难。你应该做的是在该表中添加一个自动增量bigint列,该列将成为你的新主键,而你的三列唯一性约束可以是一个唯一的索引。它应该表现得更好......但它也可以让你做你需要的那种操作。它会让你执行修改,但仍然可以让你通过整数索引来识别原始行。
如果你这样做,只要你不介意创建一些临时表来处理,你的“一次性更新”现在可以安全地完成。事情是这样的:
创建几个具有相同的架构临时表,但没有独特三列索引 - 你可以有一个非唯一索引,因为它会帮助你了解查询去表演;
将需要处理的记录复制到第一个表中(包括唯一的整数主键);
更新您需要在临时表中更新的所有detail
列;
使用INSERT ... SELECT
与SUM
和GROUP BY
将这些记录合并到第二个表中;
INSERT INTO temp2 (...whatever...) SELECT ...whatever..., SUM(no) FROM temp1 GROUP BY ...whatever...
最后,从原始表(使用整数主键)删除temp1目录表的所有记录,并插入在TEMP2表中的记录到原始表。
多列主键不是一个坏主意,你为什么这么认为。 – 2012-01-31 01:08:38
@ypercube我曾经喜欢在商业模式中使用任何“自然而然”独特的东西作为主键的想法;无论是字符串,还是多列的组合。它似乎比仅仅因为添加数字PK更有意义。但是当你必须做出不可避免的改变时,它就会变得脆弱,就像OP现在正在做的那样。 – 2012-01-31 01:25:03
OP的问题是因为他有多个具有相同的此键值(我们假设他希望它是唯一的或主要的)的行。一个简单的“GROUP BY”将收集数据。 (将这些数据放在同一个表中,并删除多行可能会非常棘手,是的。)我看不出代理键如何帮助。 – 2012-01-31 01:29:05
你能澄清吗?我假设有两行'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
没错。它实际上是合并这些行。 – DrXCheng 2012-01-30 23:19:40
从你的其他问题,虽然我猜这不是'只是'两行...你打算改变*所有*细节领域更简单(你不需要使用LIKE)和那么所有的合并都会发生? – 2012-01-30 23:21:05