I have a table which contains the items the users of my game owns. If a user buys a new item, it should be inserted, but if he already got it, it should be increased instead.
I understand I can use INSERT ... ON DUPLICATE KEY UPDATE, but I don't understand how in my problem.
The item_id isn't unique, because many players can own the same weapon (ie. a longsword). The user_id isn't unique either, because a player can own many items.
So, my question is how to make the query UPDATE instead of INSERT if a row containing both the user_id and item_id already exists?
I know this question is old but none of the answers are correct.
You need a PRIMARY or UNIQUE index on user_id and item_id (both columns in one index).
Then you can use "INSERT INTO ... VALUES ... ON DUPLICATE KEY UPDATE count=count+1" no problem.
This is EXACTLY what ON DUPLICATE UPDATE will do for you.
That's not what the "ON DUPLICATE KEY UPDATE" will do for you. If it were me, I would attempt the insert. If it failed, check why (you're checking for errors already, right?). If it's because of a duplicate key, do your update. If the error is for some other reason, then handle that appropriately.
You do want ON DUPLICATE KEY UPDATE. It looks for the Primary Key of the table, and if it exists, updates all the other rows.
So your table has a primary key of (userid, itemid) and the following values:
userid itemid strength
4 5 6
And you want to bump it to strength=9, use this:
INSERT INTO table ON DUPLICATE KEY UPDATE VALUES(4,5,9)
It will insert a row with 4,5,9 if it doesn't exist, and will update strength to 9 on the row with primary key (4,5) if it does exist. It won't update any other rows (e.g. rows with userid4 but itemid 10 or itemid 5 but userid 70) because they don't match the whole PK.
You could do something like the following (assumes your user id is in the variable UserID and item ID is in item_ID) :
SELECT
#rowCount := COUNT(*)
FROM
table
WHERE
user_id = UserID
AND item_id = ItemID;
IF (#rowCount > 0) THEN
... do update
ELSE
... do insert
END IF;
Can you do something like
UPDATE TABLE
set COL = 'BLAH BLAH'
where ITEM_ID = #itemid AND USER_ID = #userid
IF ##ROWCOUNT = 0
BEGIN
INSERT INTO TABLE (col...)
VALUES (vals...
END
Related
I am confused to how to deal with the below scenario.
I have product table and i'm inserting records in this table using bulk insert.
e.g.
INSERT INTO product (p_id,p_quantity) VALUES(1,20),(2,10),(3,30);
Now I want update p_quantity if p_id is already exists.
e.g. my next bulk insert query can be
INSERT INTO product (p_id,p_quantity) VALUES(2,15),(4,40);
So, in such case my product having p_id = 2 should get updated with 15 and total p_quantity should be 25.
NOTE: I can not apply unique key constraints on any of key as I have other scenarios.
Thank you.
You are looking for on duplicate key update:
INSERT INTO product (p_id, p_quantity)
VALUES (2,15), (4,40)
ON DUPLICATE UPDATE p_quantity = VALUES(p_quantity) + p_quantity;
This assumes that p_id is defined as unique or primary key.
If p_id is already exist you need to update it
UPDATE product
SET p_quantity = 15
WHERE p_id = 2
Then second record will be updated. After that you can insert 4th record
Hi I've been trying to get this to work, I thought I had it with mysql - INSERT... ON DUPLICATE KEY UPDATE, but no luck.
I have a table as such:
sessionID is unique,
productID references another table and is not unique, but not common, should be a max of 3 rows containing the same value,
sessionType is either 1, 2 or 3, and would link with productID,
I need to check if the table has a row where there is a matching pair of productID and sessionType, if there is then sessionDate & sessionCapacity in that row should be UPDATED, if there isn't then a new row inserted.
$vals = array($pID,$data['pSessionDate'],'1',$data['pQty'],$pID,$data['pSessionDate'],'1',$data['pQty']);
$db->Execute("INSERT INTO VividStoreSessions (pID,sDate,sType,sCapacity) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE pID=?,sDate=?,sType=?,sCapacity=?",$vals);
Hope that makes sense to someone and thanks in advance for any help!
Your insert looks valid. But, first you need a unique index/constraint:
create unique index unq_VividStoreSessions_productId_sessionType
on VividStoreSessions, productId, sessionType)
Then you can write the code to only use four parameters:
INSERT INTO VividStoreSessions (pID, sDate, sType, sCapacity)
VALUES (? ,?, ?, ?)
ON DUPLICATE KEY UPDATE sDate = VALUES(sDate), Capacity = VALUES(Capacity);
Finally, you need to ensure that sType only takes on the values of 1, 2, or 3. Perhaps you want to enforce this at the application layer. Otherwise, you need a trigger or foreign key constraint to ensure that there are only three rows.
I have the following table in mariadb:
-id = key which shall autoincrement
-price
-amount
-name
-order_id
order_id can appear twice in the table but the combination of name and order_id should be unique. I now have a combination of name and order_id.
What I want to do is to add a record if the combination of name and order_id is not in the table.
If it's in then I want to change/get the amount value.
Is there a nice query to accomplish this?
Regards
I like using on duplicate key update for this. You need to start by creating a unique index on name and order_id:
create unique index ix_table_orderid_name on table(order_id, name);
Then the insert looks like:
insert into table(price, amount, name, order_id)
values (#price, #amount, #name, #order_id)
on duplicate key update amount = values(amount), price = values(price);
This replaces the values in the table with the new values. You can also increment them. Your question is unclear on the exact operation.
Having a bit of a problem. Firstly, here's my table structure.
Table doc_perms
id user_id doc_id can_view can_edit can_delete
ID being the PK and user_id and doc_id being FK's of other tables.
Basically, what I need is to prevent an INSERT query from executing if the INSERT data for user_id and doc_id already exists in a row regardless of the rest of the columns.
For example
if you have the data
user_id doc_id
1 1
1 2
And then you try do an INSERT with user_id = 1 and doc_id = 2, the query fails because there's already a row with that data in it.
Hope this makes sense.
Appreciate your help in advance.
Assuming there are no duplicates in doc_perms, you can create a unique index on (user_id, doc_id):
CREATE UNIQUE INDEX doc_perms_index
ON doc_perms (user_id,doc_id)
If there are duplicates, you can use ALTER IGNORE ... ADD UNIQUE INDEX will remove them:
ALTER IGNORE TABLE doc_perms
ADD UNIQUE INDEX doc_perms_index (user_id, doc_id)
(Among all rows that share the same (user_id, doc_id), all the rows except one will be dropped. The row that is kept is unspecified.)
After you create the unique index, INSERT INTO doc_perms ... will raise an error if (user_id, doc_id) is a duplicate.
If you wish to INSERT, but UPDATE other columns when (user_id, doc_id) is a duplicate, then (as #moopet has already mentioned) you can use INSERT ... ON DUPLICATE KEY UPDATE. For example:
INSERT INTO doc_perms (user_id, doc_id, foo)
VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE foo = 3'''
You can use INSERT ... ON DUPLICATE KEY UPDATE
See the MySQL manual here: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
I have a chat user entry in a MySql table -
id (primary key, autoincrement) - the chat user id
user_id - the users id as it pertains to our product
room_id - the id of the room your in
If a chat operator enters the room, leaves, and then comes back - as it is now - will create two entries in the room (INSERT INTO chatuser ...)
I know INSERT IF NOT EXISTS syntax, however I want to IF NOT EXISTS not on the primary key, but WHERE user_id = x AND room_id = y (which will be the same if they re-enter a room they have been in)
something like INSERT INTO chatuser SET user_id=4, room_id=2 IF ENTRY DOESNT EXIST WITH THOSE VALUES ALREADY ;)
thank you
If you have a unique index on (user_id,room_id), you can do INSERT ... ON DUPLICATE KEY UPDATE (or INSERT IGNORE if you don't need to update anything when the record already exists):
INSERT INTO table_1 (user_id, room_id, enter_date)
VALUES (1,1, NOW())
ON DUPLICATE KEY UPDATE
enter_date = NOW()
// or
INSERT IGNORE INTO table_1 (user_id, room_id)
VALUES (1,1)
I think what we have here is a design issue. You have 3 tables, a user table, a room table and a table that links that two. The last one is what we're working with here. Now, if you want to log every time a user enters a room, the table design you have is ideal. However it seems that is not what you are doing. It seems you want an entry for just the last visit. In this case your table should not have an auto incrementing primary key, and instead should have userID and roomID to both be parts of a multi-column primary key.
Modify your table to that set-up then run your insert statement with ON DUPLICATE KEY UPDATE clause.