我有这个insert into select duplicate key update
查询,但是执行两次之后,行数增加了一倍。堆栈溢出要我添加文本,所以我现在只是写东西,因为我认为你们不需要更多的解释,因为此查询是很容易解释的。
编辑1:为澄清:它不应该加倍,我希望数据得到更新。
编辑2:表信息
CREATE TABLE `Distance` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`distanceType_myId` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`common_id` int(11) NOT NULL,
`distance` double NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=786421 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
编辑3:更新表信息
CREATE TABLE `Distance` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`distanceType_myId` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`common_id` int(11) NOT NULL,
`distance` double NOT NULL,
PRIMARY KEY (`id`),
KEY `uniqueId` (`distanceType_myId`,`common_id`)
) ENGINE=InnoDB AUTO_INCREMENT=786421 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
实际查询:
INSERT INTO Distance (common_id, distance, distanceType_myId)
SELECT
c.id,
AVG(
ROUND(
(
6371 * acos(
cos(
radians(p.lat)
) * cos(
radians(a.lat)
) * cos(
radians(a.lng) - radians(p.lng)
) + sin(
radians(p.lat)
) * sin(
radians(a.lat)
)
)
)* 1000
)
) AS distance,
'culturel' AS distanceType
FROM
immobilier_ad_blank AS c
LEFT JOIN Adresse AS a ON c.adresse_id = a.id
JOIN POI AS p on p.discr = 'Culturel'
AND p.lat IS NOT NULL
AND p.lng IS NOT NULL
AND p.lat != ''
AND p.lng != ''
AND p.lat != 'Latitude'
AND p.lng != 'Longitude'
WHERE
ROUND(
(
6371 * acos(
cos(
radians(p.lat)
) * cos(
radians(a.lat)
) * cos(
radians(a.lng) - radians(p.lng)
) + sin(
radians(p.lat)
) * sin(
radians(a.lat)
)
)
)* 1000
)< 5000
AND a.lat IS NOT NULL
AND a.lng IS NOT NULL
AND a.lat != ''
AND a.lng != ''
AND a.lat != 'Latitude'
AND a.lng != 'Longitude'
GROUP BY
c.id
ON DUPLICATE KEY
UPDATE
common_id = VALUES(common_id),
distanceType_myId = VALUES(distanceType_myId)
很简单,您没有唯一的密钥。在表中,您需要一个唯一的标识符或自然键,而不是一个替代的标识符(主键)。
主键与数据无关,它们是代理键。例如,您无法查看行并知道它的主键是一个没有主键的主键。
自然键类似于仅名称数据库中的名称,或者电话号码数据库中的电话号码,它可以是状态数据库中的状态。您不会有两个密歇根州或俄亥俄州的条目,例如,它们本身具有独特性。
代理键很适合用于关系或用作外键,因为它们与数据无关。一个不好的例子是,如果美国突然决定在该州的缩写中添加字母。您将必须更新所有关系。换句话说,您可以更改状态记录,而不必更改数据库中的任何其他数据,因为代理键与该数据无关。(一个更好的例子是在北密歇根州和南密歇根州生产)
因此,每个人都有自己的用途和存在的理由。
更新
INSERT INTO
Distance (common_id, distance, distanceType_myId)
VALUES ( 1,20.0,'culturel' )
ON DUPLICATE KEY UPDATE
id = LAST_INSERT_ID( id ),
common_id = VALUES( common_id ),
distance = VALUES( distance ),
distanceType_myId = VALUES( distanceType_myId )
这是我过去阅读一些旧代码的方法,然后它也会更新插入ID。
UPDATE1.1但是,在测试中发现的所有内容表明,如果您将PDO与异常一起使用,则可以通过忽略错误来提高插入性能。也就是说,如果您实际上不想更新该行,或者不需要ID。例如,如果您只是插入而不想重复。(例如,仅未经测试的代码)
try{
$PDO->query( "INSERT INTO
Distance (common_id, distance, distanceType_myId)
VALUES ( 1,20.0,'culturel' )" );
}catch( PDOException $e){
if($e->getCode() != 24000 ){ //not 100% sure of the code number
//rethrow if not duplicate key
throw new PDOException( $e->getMessage(), $e->getCode(), $e );
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句