업데이트 부분에서 새 값과 이전 값을 모두 사용할 수 있도록 UPSERT를 수행하는 방법
어리석지만 간단한 예:수신한 항목의 합계를 보관하는 테이블 '항목'이 있다고 가정합니다.
Item_Name Items_In_Stock
여기서 항목 이름은 기본 키입니다.A 아이템을 수량 X로 받을 때마다 어떻게 하면 다음 사항을 달성할 수 있을까요?
아이템이 존재하지 않는 경우 아이템 A에 대해 새로운 점수를 매겨 재고품을 X로 설정하고 재고품이 Y였던 기록이 있는 경우 재고품의 새로운 값은 (X+Y)입니다.
INSERT INTO `item`
(`item_name`, items_in_stock)
VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE
`new_items_count` = 27 + (SELECT items_in_stock where item_name = 'A' )
문제는 실제 테이블에 열이 여러 개 있다는 것입니다.업데이트 부분에 여러 개의 선택문을 작성하는 것이 좋은 생각입니까?
물론 암호로도 가능하지만 더 좋은 방법이 있을까요?
코멘트에서도 언급했듯이 ON DUPLICE KEY를 기동시키는 행을 참조하기 위해서 서브셀렉트를 실시할 필요는 없습니다.따라서 이 예에서는 다음을 사용할 수 있습니다.
INSERT INTO `item`
(`item_name`, items_in_stock)
VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE
`new_items_count` = `new_items_count` + 27
대부분의 일은 매우 간단하다는 것을 기억하십시오.심플해야 할 일을 지나치게 복잡하게 만들고 있는 자신을 발견하면 잘못된 방법으로 하고 있을 가능성이 높습니다.
Michael의 답변은 맞지만 프로그래밍 방식으로 업어트를 수행하려면 조금 더 알아야 합니다.
먼저 테이블을 만들고 고유한 인덱스를 사용할 열을 지정합니다.
CREATE TABLE IF NOT EXISTS Cell (
cellId BIGINT UNSIGNED,
attributeId BIGINT UNSIGNED,
entityRowId BIGINT UNSIGNED,
value DECIMAL(25,5),
UNIQUE KEY `id_ce` (`cellId`,`entityRowId`)
)
그런 다음 몇 가지 값을 삽입합니다.
INSERT INTO Cell VALUES( 1, 6, 199, 1.0 );
동일한 작업을 다시 시도하면 중복 키 오류가 발생합니다.cellId
그리고.entityRowId
동일:
INSERT INTO Cell VALUES( 1, 6, 199, 1.0 );
키 'id_ce'에 대한 항목 '1-199'가 중복됩니다.
그렇기 때문에 upsert 명령어를 사용합니다.
INSERT INTO Cell ( cellId, attributeId, entityRowId, value)
VALUES( 1, 6, 199, 300.0 )
ON DUPLICATE KEY UPDATE `value` = `value` + VALUES(`value`)
이 명령어는 다음 값을 사용합니다.1.0
이미 가치로 존재하고, 그것을 실현합니다.value = value + 300.0
.
따라서 위의 명령어를 실행해도 테이블에는 행이1개밖에 없고 값은301.0
.
이 예에서 아이디어를 얻을 수 있습니다.
사용자 정의 7일 데이터를 추가한다고 가정합니다.
userid 및 day에 고유한 값을 지정해야 합니다.
UNIQUE KEY `seven_day` (`userid`,`day`)
여기 테이블이 있습니다
CREATE TABLE `table_name` (
`userid` char(4) NOT NULL,
`day` char(3) NOT NULL,
`open` char(5) NOT NULL,
`close` char(5) NOT NULL,
UNIQUE KEY `seven_day` (`userid`,`day`)
);
그리고 당신의 질문은
INSERT INTO table_name (userid,day,open,close)
VALUES ('val1', 'val2','val3','val4')
ON DUPLICATE KEY UPDATE open='val3', close='val4';
예:
<?php
//If your data is
$data= array(
'sat'=>array("userid"=>"1001", "open"=>"01.01", "close"=>"11.01"),
'sun'=>array("userid"=>"1001", "open"=>"02.01", "close"=>"22.01"),
'sat'=>array("userid"=>"1001", "open"=>"03.01", "close"=>"33.01"),
'mon'=>array("userid"=>"1002", "open"=>"08.01", "close"=>"08.01"),
'mon'=>array("userid"=>"1002", "open"=>"07.01", "close"=>"07.01")
);
//If you query this in a loop
//$conn = mysql_connect("localhost","root","");
//mysql_select_db("test", $conn);
foreach($data as $day=>$info) {
$sql = "INSERT INTO table_name (userid,day,open,close)
VALUES ('$info[userid]', '$day','$info[open]','$info[close]')
ON DUPLICATE KEY UPDATE open='$info[open]', close='$info[close]'";
mysql_query($sql);
}
?>
데이터가 표에 표시됩니다.
+--------+-----+-------+-------+
| userid | day | open | close |
+--------+-----+-------+-------+
| 1001 | sat | 03.01 | 33.01 |
| 1001 | sun | 02.01 | 22.01 |
| 1002 | mon | 07.01 | 07.01 |
+--------+-----+-------+-------+
이것은 상승에 대한 구문입니다.
INSERT INTO `{TABLE}` (`{PKCOLUMN}`, `{COLUMN}`) VALUES (:value)
ON DUPLICATE KEY UPDATE `{COLUMN}` = :value_dup';
PK 열 또는 유니시티를 충족하는 열에 고유 인덱스에 대한 값이 있는 경우 다음을 사용할 수 있습니다.INSERT IGNORE
,INSERT INTO ... ON DUPLICATE
, 또는REPLACE
의 예INSERT IGNORE
INSERT IGNORE INTO Table1
(ID, serverID, channelID, channelROLE)
VALUES
(....);
의 예INSERT INTO .. ON DUPLICATE KEY UPDATE
SET @id = 1,
@serverId = 123545,
@channelId = 512580,
@channelRole = 'john';
INSERT INTO Table1
(ID, serverID, channelID, channelROLE)
VALUES
(@id, @serverId, @channelId, @channelRole)
ON DUPLICATE KEY UPDATE
serverId = @serverId,
channelId = @channelId,
channelRole = @channelRole;
의 예Replace
REPLACE INTO table1
(ID, serverID, channelID, channelROLE)
VALUES
(...);
상승의 예
INSERT INTO table1 (col1, col2, col3)
VALUES ($1, $2, $3)
ON CONFLICT (col1)
DO
UPDATE
SET col2 = $2, col3 = $3
WHERE col1 = $1
RETURNING col1
언급URL : https://stackoverflow.com/questions/6107752/how-to-perform-an-upsert-so-that-i-can-use-both-new-and-old-values-in-update-par
'programing' 카테고리의 다른 글
JUnit 테스트 케이스에서 MySQL을 실행하는 방법이 있습니까? (0) | 2023.01.15 |
---|---|
SyntaxError: 비ASC함수가 '''을 반환할 때 파일의 II 문자 '\xa3' (0) | 2023.01.15 |
AttributeError: 'module' 개체에 속성이 없습니다. (0) | 2023.01.06 |
중첩 루프 차단 (0) | 2023.01.05 |
비어 있지 않은 폴더를 삭제/삭제하려면 어떻게 해야 합니까? (0) | 2023.01.05 |