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
Related
I have table where I wanted to store one more key for each user, following is the table,
I was trying to add app_reminder for each existing users. I did it by following
insert into users_settings (user_id, key)
select distinct user_id, 'app_reminder'
from users_settings;
Now I want to add where clause
SELECT DISTINCT user_id, 'app_reminder' WHERE key != 'app_reminder'
for preventing duplicate entries. I tried above one but it does not working.
Can someone kindly guide me about it, I would appreciate.
Thank you
One method simply uses conditional aggregation:
insert into users_settings (user_id, key)
select user_id, 'app_reminder'
from users_settings
group by user_id
having sum(key = 'app_reminder') = 0;
You might want a more generic solution. If you want to ensure that user/key pairs are never duplicated, then create a unique constraint or index on those columns:
alter table users_settings add constraint unq_users_settings_user_id_key
unique (user_id, key);
Then, you can skip inserting the rows using on duplicate key update:
insert into users_settings (user_id, key)
select distinct user_id, 'app_reminder'
from users_settings
on duplicate key update user_id = values(user_id);
The update does nothing, because the value is the same. MySQL skips doing the insert and does not return an error.
I have SQL code, how should I change it to insert datas only if they aren't exist in my table. thanks for your answers:)
INSERT INTO stages_done(id_booked_proj, id_stage)
SELECT booked_proj.id, stages.id_st
FROM booked_proj, stages
WHERE booked_proj.name='home' AND stages.name_st= 'sm'"
You can use INSERT IGNORE, this way the row won't be inserted if it results in a duplicate key:
INSERT IGNORE INTO stages_done(id_booked_proj, id_stage)
SELECT booked_proj.id, stages.id_st
FROM booked_proj, stages
WHERE booked_proj.name='home' AND stages.name_st= 'sm'"
Any duplicate key in columns either with PRIMARY KEY or UNIQUE constraints will be ignored.
If you have writing access, you can add a constraint to your table, like this:
ALTER TABLE `stages_done` ADD UNIQUE `id_booked_proj_id_stage_index` (`id_booked_proj`, `id_stage`);
Where id_booked_proj_id_stage_index can be any name you pick as long as it is unique.
I have three columns on my database table
user_id, post_id, and vote
I want to insert a new data if user_id and post_id don't exist. But if both columns user_id and post_id exist i will be able to update 'vote' column value. I set user_id to be unique but it proves to be not working since i want user to insert votes on different post.
The query below only updated the value of vote since user_id already exist. I want to have it updated if and only if user_id and post_id existed
I used this sql query
INSERT INTO polls (user_id,post_id,vote) VALUES (1,2,5)
ON DUPLICATE KEY UPDATE vote= ?;
Here's my problem
You must create unique key combination
Create unique index your_index_name on yourtable (field_one,field_two),
then do the insert into , on duplicate key logic
It is absolutely logical that your code does not work as intended, because your only key is user_id, thus if you want to check the uniqueness of user_id AND post_id, then you should set it as so.
Don't think you can do it purely in MySQL :*( post_id would have to be unique and you said that does not fit your business logic. Furthermore, if multiple keys are detected, they are joined by an OR in the resulting query, which will further complicate things for you. Here's an excerpt from the manual, where a and b are keys involved in the ON DUPLICATE KEY query:
If a=1 OR b=2 matches several rows, only one row is updated. In general, you should try to avoid using an ON DUPLICATE KEY UPDATE clause on tables with multiple unique indexes.
i want to insert rows IF a row containing the specific values exists, and if not update it.
Concretely:
A column user_id=5, user_zip=12345, distance=600 exists on the database.
If i try to insert user_id=5, user_zip=12345, distance=700 it should just update the distance
but i try to insert user_id=5, user_zip=67890, distance=800 it should insert a new row.
I can't define the columns user_zip and distance unique, so that i can use the on duplicate key update.
I think you are misunderstanding how ON DUPLICATE KEY UPDATE works. With a unique constraint on (user_id, user_zip), this should work:
INSERT INTO yourTable (user_id, user_zip, distance) VALUES (5,12345,600)
ON DUPLICATE KEY UPDATE distance=600;
You don't have to define user_zip unique (that's how I understand your question), just the combination of user_id and user_zip. So you still can have 2 or more rows with the same user_id, just the user_zip can't match on those rows.
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