このinsert into select duplicate key update
クエリがありますが、2回実行すると、行数が2倍になります。スタックオーバーフローは私にテキストを追加することを望んでいるので、このクエリは非常に自明であるため、皆さんがこれ以上説明する必要はないと思うので、現時点では何かを書いています。
編集1:明確にするために:それは2倍になるべきではありません、私はデータを更新したいです。
編集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)
単純です。一意のキーはありません。テーブルには、代理の識別子(主キー)ではなく、一意の識別子または自然キーが必要です。
主キーはデータとは関係がなく、代理キーです。たとえば、行を見て、その主キーが主キーを持たないものであることを知ることはできません。
自然キーは、名前のみのデータベース内の名前、または電話番号のデータベース内の電話番号のようなものであり、状態のデータベース内の状態である可能性があります。ミシガン州またはオハイオ州のエントリは2つありません。たとえば、それらは独自の権利で一意です。
代理キーは、データに関連していないため、関係に適しているか、外部キーとして使用できます。悪い例は、突然米国が州の略語に文字を追加することを決定した場合です。あなたはあなたのすべての関係を更新しなければならないでしょう。つまり、代理キーはデータに関連していないため、状態レコードを変更でき、データベース内の他のデータを変更する必要はありません。(より良い例は、北と南のミシガンを作ることです)
したがって、それぞれに独自の用途と存在理由があります。
更新
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]
コメントを追加