Mysql 重复密钥更新时的SQL更新

Mysql 重复密钥更新时的SQL更新,mysql,sql,database-design,Mysql,Sql,Database Design,我问过这个问题,但我没有得到答案 我有一个表:名称、日期、详细信息、否,和名称、日期、详细信息一起作为主键 不知何故,我需要更新详细信息,可能存在重复的密钥。因此,我需要对重复行的no求和仅用于插入。那么如何解决这个问题呢?糟糕的设计。您应该使用代理id主键,并使这些字段成为复合唯一索引。如果你以后想引用这个表,你会有什么?3个额外字段作为另一个表中的外键和一个超大索引。您将如何更新详细信息字段?如果你在它是一个大表之前说过,这意味着PK索引重建。如果可能以及约束尚未被引用,请禁用该约束。使源表

我问过这个问题,但我没有得到答案

我有一个表:
名称、日期、详细信息、否
,和
名称、日期、详细信息
一起作为主键


不知何故,我需要更新
详细信息
,可能存在重复的密钥。因此,我需要对重复行的
no
求和<重复密钥更新时的代码>仅用于插入。那么如何解决这个问题呢?

糟糕的设计。您应该使用代理id主键,并使这些字段成为复合唯一索引。如果你以后想引用这个表,你会有什么?3个额外字段作为另一个表中的外键和一个超大索引。您将如何更新详细信息字段?如果你在它是一个大表之前说过,这意味着PK索引重建。如果可能以及约束尚未被引用,请禁用该约束。使源表中的select distinct或group by不同,并使用此select进行更新


替换编辑:

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

糟糕的设计。您应该使用代理id主键,并使这些字段成为复合唯一索引。如果你以后想引用这个表,你会有什么?3个额外字段作为另一个表中的外键和一个超大索引。您将如何更新详细信息字段?如果你在它是一个大表之前说过,这意味着PK索引重建。如果可能以及约束尚未被引用,请禁用该约束。使源表中的select distinct或group by不同,并使用此select进行更新


替换编辑:

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

首先,多列主键可能是个坏主意;正如您所发现的,这使得操纵单个字段变得很困难。您应该做的是向该表添加一个autoincrement bigint列,它将成为您的新主键,而您的三列唯一性约束可以改为唯一索引。它应该表现得更好。。。但它也可以让你进行你需要的操作。它允许您执行修改,但仍然允许您通过整数索引标识原始行

如果您这样做,您的“一次性更新”现在可以安全地完成,只要您不介意创建一些临时表来使用。大概是这样的:

使用相同的模式创建两个临时表,但不使用唯一的三列索引-您可以使用非唯一索引,因为它将帮助您执行查询

将需要处理的记录复制到第一个表中(包括唯一的整数主键)

更新临时表中所有需要更新的
detail

使用
插入。。。选择
with
SUM
和GROUP BY,将这些记录合并到第二个表中

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

最后,从原始表中删除temp1表中的所有记录(使用整数主键),并将temp2表中的记录插入原始表。

首先,多列主键可能是个坏主意;正如您所发现的,这使得操纵单个字段变得很困难。您应该做的是向该表添加一个autoincrement bigint列,它将成为您的新主键,而您的三列唯一性约束可以改为唯一索引。它应该表现得更好。。。但它也可以让你进行你需要的操作。它允许您执行修改,但仍然允许您通过整数索引标识原始行

如果您这样做,您的“一次性更新”现在可以安全地完成,只要您不介意创建一些临时表来使用。大概是这样的:

使用相同的模式创建两个临时表,但不使用唯一的三列索引-您可以使用非唯一索引,因为它将帮助您执行查询

将需要处理的记录复制到第一个表中(包括唯一的整数主键)

更新临时表中所有需要更新的
detail

使用
插入。。。选择
with
SUM
和GROUP BY,将这些记录合并到第二个表中

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

最后,从原始表中删除temp1表中的所有记录(使用整数主键),并将temp2表中的记录插入原始表。

您能澄清一下吗?我假设有两行
name=A,date=B,detail=C,no=23
name=A,date=B,detail=D,no=45
-如果你想这样做,那么如果你把第二行的detail更新为C,这两行加起来就是一行
name=A,date=B,detail=C,no=68
?但是只有当
名称
日期
字段也匹配时,才可以这样做。它实际上是在合并这些行。从你的另一个问题来看,虽然我猜这不是“仅仅”两行。。。您的目标是将所有细节字段更改为更简单的字段(您不需要像上一样使用),然后进行所有合并?您能澄清一下吗?我假设有两行
name=A,date=B,detail=C,no=23
name=A,date=B,detail=D,no=45
-如果你想这样做,那么如果你把第二行的detail更新为C,这两行加起来就是一行
name=A,date=B,detail=C,no=68
?但是只有当
名称
日期
字段也匹配时,才可以这样做。它实际上是在合并这些行。从你的另一个问题来看,虽然我猜这不是“仅仅”两行。。。您的目标是将所有细节字段更改为更简单的字段(您不需要像在上一样使用),然后进行所有合并?PK不会经常更新。我只想做一次更新。好的,你可以用替换。非常感谢。您能给出一个简单的例子吗?在运行表之前,先复制一份表,然后在那里运行它并阅读文档ca