My columns are like this. column "a" is primary and auto incremantal.
a | b | x | y
When inserting new data, i need to check x and y columns shouldn't be exist together.
To clarify, imagine this row is at database with these values
(2, "example.com" , "admin", "123456")
I should able to insert both of these columns
(3, "example.com" , "user", "123456")
(4, "example2.com" , "admin", "123456")
But i shouldn't able to insert this column
(5, "example.com" , "admin", "5555555")
Because "example.com" and "admin" values already in database on a row. It doesn't matter column "y" is same or not.
How can i do this?
Create a composite unique index. This will allow any number of duplicates in the individual fields, but the combination needs to be unique.
CREATE UNIQUE INDEX ix_uq ON tablename (b, x);
...and use INSERT IGNORE to insert if the unique index is not violated. If it is, just ignore the insert.
INSERT IGNORE INTO test (a,b,x,y) VALUES (5, "example.com" , "admin", "5555555");
If you want to insert unless there's a duplicate, and update if there is, you can also use INSERT INTO ... ON DUPLICATE KEY UPDATE;
Ref: MySQL only insert new row if combination of columns (which allow duplicates) is unique
You want to let the database do the work. Although you can set up a condition within a query, that condition may not be universally true or someone might use another query.
The database can check this with a unique constraint or index. Actually, the unique constraint is implementing using a unique index:
create unique index unq_t_b_x on t(b, x);
(The columns can be in either order.)
The insert would then look like:
insert into t(b, x, y)
values ('example.com', 'admin', '5555555')
on duplicate key update b = values(b);
Note that the auto-incremented value is not included in the update.
The on duplicate key update just prevents the insert from generating an error. It is better than insert ignore because the latter will ignore all errors, and you just want to ignore the one caused by the duplicate key.
Related
I have two tables, one of them is 'user_flag' and the other is 'playlist_data'.
I want to take all 'object_id' column entries of 'user_flag' and place them into the respective 'object_id' column of 'playlist_data', but only if those entries have '3' as the 'user' entry, and that they do not already exist (no duplicate 'object_id's!).
I tried to learn how to do it and this is what I found:
INSERT INTO playlist_data (object_id)
SELECT object_id FROM user_flag
WHERE user='3';
ON DUPLICATE KEY UPDATE object_id=object_id
Will this work properly?
But I'm also trying to do more at the same time, and I can't seem to find an answer:
1) I want to also insert new data with this. I want all of the newly inserted entries to also contain '5' in the 'filetype' column of 'playlist_data'.
Do I just
INSERT INTO playlist_data (filtype)
VALUES (5)
in the middle of all of this?
2) Both tables also have an 'id' column, will it automatically generate a new id followed from the latest 'id' of 'playlist_data'?
As in for example, I'm transferring from 'user_flag' an entry with the 'id' of '150', while the highest 'id' in 'playlist_data' is '63', will the inserted one by '64', or do I need to define that somehow?
Just add the value in the SELECT:
INSERT INTO playlist_data (object_id, filtype)
SELECT object_id, 5
FROM user_flag
WHERE user = 3
ON DUPLICATE KEY UPDATE object_id = VALUES(object_id);
Notes:
I am guessing that the id columns are numbers. Hence, I removed the single quotes.
I use VALUES(object_id) in the ON DUPLICATE KEY UPDATE.
It is important to have the semicolon only at the very end of the statement.
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'm trying to set a unique restraint on a combination of columns rather than on a single column. I have a table, "tags":
id (int, PK, AI, unsigned)
tag (varchar 25)
user_id (int, unsigned)
Following the answer to this question, I tried to set the combo restraint via:
ALTER TABLE `tags` ADD UNIQUE `unique_tag_user_combo` (`tag`, `user_id`);
So far, so good. But when I come to test it, by seeing if it will let me insert the same tag twice but with different user IDs (it should), it errors:
INSERT INTO `tags` VALUES (NULL, 'foo', '1'), (NULL, 'foo', '2')
...throws...
Duplicate entry 'foo' for key 'name_2'
Remember the unique restraint is on the combo of tag + user_id, so this query, to my mind, should run fine. I could understand this error if I'd tried to insert foo/1 twice, but not foo/1 and foo/2. What am I missing?
(EDIT - also, what's that 'name_2' reference in the error message all about? I don't have a column with that name...)
You might also have an unique index on tag column.Use
SHOW CREATE TABLE yourtb
I'm pretty much a complete newbie to SQL, I'm using MySQL with SQLyog. I have five fields, StudentForename, StudentSurname, StudentAge, StudentHouse and StudentID for the Primary Key. The StudentID field is set as a Primary Key and Not Null and AutoIncrement. I'm trying to use an INSERT INTO statement without having to entering the primary key - apparently I shouldn't need to, it should update itself. But it's not working, it's returning the error "Column count doesn't match value count at row 1". Here's the code I'm using. I've already set up the table, so I haven't got the code for the query that
INSERT INTO students VALUES('Harry', 'Potter', 'Slytherin', 30)
You will need to explicitly state which columns you will provide values for, otherwise it is assumed you will provide values for all columns. E.g.
INSERT INTO students (`first_name`, `last_name`, `house`, `age`) VALUES('Harry', 'Potter', 'Slytherin', 30)
(I made up column names, swap these with your columns)
I have a table with with essentially three columns: user_id, setting, and value. I'm trying to use the following code:
INSERT INTO 'user_settings'(user_id, setting, value)
VALUES (1234, setting_1, 500)
ON DUPLICATE KEY UPDATE user_id = 1234, setting = setting_1'
This works great when creating a new setting, and it doen't generate duplicate records. The problem comes when I want to change the value- this won't work after the previous query has run:
INSERT INTO 'user_settings'(user_id, setting, value)
VALUES (1234, setting_1, 999)
ON DUPLICATE KEY UPDATE user_id = 1234, setting = setting_1'
No rows are affected. Clearly I'm missing something...
IMPORTANT: I am not able to alter the database (new primary keys or something).
UPDATE: It seems my understanding of ON DUPLICATE KEY is wrong. But the question remains- what is the most efficient way way to accomplish this?
Answered in a comment below: "If the Primary (or Unique) key is (user_id, setting), then use: ... ON DUPLICATE KEY UPDATE value=999".
Assuming you actually have a unique key on user_id, you are getting "no rows affected" because you aren't changing anything in the second query. I think what you want to do is update the value field as well:
INSERT INTO 'user_settings'(user_id, setting, value)
VALUES (1234, setting_1, 999)
ON DUPLICATE KEY UPDATE setting = setting_1,value=999
Without value in there, you're just setting the user_id and the setting field to the same values they were before, and MySQL doesn't need to update the record.
If you don't have a unique key on user_id, you'll have to find a different approach, as the ON DUPLICATE KEY UPDATE won't trigger.