업데이트 부분에서 새 값과 이전 값을 모두 사용할 수 있도록 UPSERT를 수행하는 방법
어리석지 만 간단한 예 :받은 항목의 합계를 보관하는 테이블 '항목'이 있다고 가정합니다.
Item_Name Items_In_Stock
여기서 항목 이름은 기본 키입니다. 수량 X의 품목 A를받을 때 다음을 달성하는 방법.
항목이 존재하지 않는 경우 항목 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' )
내 문제는 실제 테이블에 여러 열이 있다는 것입니다. 업데이트 부분에 여러 개의 select 문을 작성하는 것이 좋은 생각입니까?
물론 코드로 할 수 있지만 더 좋은 방법이 있습니까?
내 의견에서 언급했듯이 ON DUPLICATE KEY를 발생시키는 행을 참조하기 위해 하위 선택을 수행 할 필요가 없습니다. 따라서 귀하의 예에서 다음을 사용할 수 있습니다.
INSERT INTO `item`
(`item_name`, items_in_stock)
VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE
`new_items_count` = `new_items_count` + 27
대부분의 일은 정말 간단하다는 것을 기억하십시오. 단순해야하는 무언가를 지나치게 복잡하게 만드는 것은 잘못된 방식으로 수행 할 가능성이 높습니다. :)
이 예제에서 아이디어를 얻을 수 있습니다.
사용자 현명한 7 일 데이터를 추가한다고 가정 해 보겠습니다.
사용자 ID 및 요일에 대해 고유 한 값이 있어야합니다.
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 |
+--------+-----+-------+-------+
Michael의 대답이 옳지 만 프로그래밍 방식으로 upsert를 수행하려면 조금 더 알아야합니다.
먼저 테이블을 만들고 고유 인덱스를 원하는 열을 지정합니다.
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 );
Try doing the same thing again, and you'll get a duplicate key error, because cellId
and entityRowId
are same:
INSERT INTO Cell VALUES( 1, 6, 199, 1.0 );
Duplicate entry '1-199' for key 'id_ce'
That's why we use the upsert command:
INSERT INTO Cell ( cellId, attributeId, entityRowId, value)
VALUES( 1, 6, 199, 300.0 )
ON DUPLICATE KEY UPDATE `value` = `value` + VALUES(`value`)
This command takes the value 1.0
that's already there as value and does a value = value + 300.0
.
So even after executing the above command, there will be only one row in the table, and the value will be 301.0
.
This is the syntax for an upsert
INSERT INTO `{TABLE}` (`{PKCOLUMN}`, `{COLUMN}`) VALUES (:value)
ON DUPLICATE KEY UPDATE `{COLUMN}` = :value_dup';
If you have value for PK Column, or Unique Index on a column which satisfies unicity, You can use INSERT IGNORE
, INSERT INTO ... ON DUPLICATE
, or REPLACE
Example with INSERT IGNORE
INSERT IGNORE INTO Table1
(ID, serverID, channelID, channelROLE)
VALUES
(....);
Example with 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;
Example with Replace
REPLACE INTO table1
(ID, serverID, channelID, channelROLE)
VALUES
(...);
'developer tip' 카테고리의 다른 글
Visual Studio 2010을 사용하여 명령 줄에서 C # 솔루션 빌드 (0) | 2020.11.23 |
---|---|
mysqldump : 백업 할 때 삽입 할 열 이름 생성 (0) | 2020.11.23 |
Jquery에서 확인란이 선택되었을 때 수신하는 방법 (0) | 2020.11.23 |
Blogger에서 구문 하이 라이터를 설정하려면 어떻게합니까? (0) | 2020.11.23 |
함수 서명에서 변수 이름 앞의 * 및 **는 무엇을 의미합니까? (0) | 2020.11.23 |