I have the following table:
questions_answers
_____________________________________
| id | question_id | answer | user_id |
|____|_____________|________|_________|
| 1 | 1 | yes | 3 |
|____|_____________|________|_________|
I want to check if question_id and user_id exist, Then update the existing row.
I tried this command INSERT INTO questions_answers (question_id, answer, user_id) VALUES (1, 'no',3) ON DUPLICATE KEY UPDATE answer = 'no'
So in this case there is a question_id = 1 and user_id = 3, Hence it should update that row and not insert a new row.
But I think it checks the id column for dublicates.
Is there is a way to get this done with SQL or I need to check if row exists with PHP, then update?
Your INSERT INTO .. ON DUPLICATE KEY UPDATE is not working because the current KEY that determine the duplication/violation is the id column primary key.
From the spec of this syntax
INSERT ... ON DUPLICATE KEY UPDATE is a MariaDB/MySQL extension to the INSERT statement that, if it finds a duplicate unique or primary key, will instead perform an UPDATE.
To achieve this, you will need to create a UNIQUE CONSTRAINT on two columns question_id and user_id. This unique constraint will raise upon the duplication of question_id - user_id pair, and triggers the UPDATE statement as you intends.
ALTER TABLE questions_answers ADD CONSTRAINT uq_user_question UNIQUE KEY(question_id ,user_id);
Reference:
MySQL Insert On Duplicate
MariaDB - INSERT ON DUPLICATE KEY UPDATE
Related
I've this table skills here (id = auto increment & primary key):
| id | skill |
--------------
| 1 | PHP |
--------------
In this table I've the skill PHP. To insert a new skill I need to check if the skill already exists. I've tried it this way but it's not working. I'm not so familiar with MySQL / SQL:
Should not work:
INSERT INTO skills (`skill`) VALUES (`PHP`) ON DUPLICATE KEY UPDATE `skill` = `PHP`;
Should work:
INSERT INTO skills (`skill`) VALUES (`HTML`) ON DUPLICATE KEY UPDATE `skill` = `HTML`;
This is the right command:
INSERT INTO skills (`skill`)
VALUES ('PHP') -- fixed the backticks
ON DUPLICATE KEY UPDATE `skill` = 'PHP';
I assume the backticks are a typo. They should be single quotes.
Although I would write it as:
INSERT INTO skills (skill)
VALUES ('PHP')
ON DUPLICATE KEY UPDATE skill = VALUES(skill);
This will only "work" if you have a unique constraint on skill:
create unique index unq_skills_skill on skills(skill);
I would simply add an unique key on skills and use insert ignore
INSERT IGNORE INTO skills (`skill`) VALUES (`PHP`)
You can then use mysql_affected_rows() to verify whether any record added or not, if it returns 0 then no record added because of duplicate.
What I have is a table of completed training. Each user has a username. Each user may completed numerous courses.
The table has the following headers:
+-------------------------+----------+---------+---------+---------+---------+-----------+
| recordnumber (KEY - AI) | username | type | course | status | started | completed |
+-------------------------+----------+---------+---------+---------+---------+-----------+
| int | varchar | varchar | varchar | varchar | date | date |
+-------------------------+----------+---------+---------+---------+---------+-----------+
And I have a PHP script set up to populate the db from a CSV upload.
What I'm trying to achieve is for it to add new rows, and to update existing ones.
The problem is that recordnumber (they key, unique field) is not constant. So instead of doing a "ON DUPLICATE KEY" query, I want to do it based on whether username and course already exist as a row.
Basically to say "If this username already has this course, update the other fields. If the username does not have this course, add this as a new row".
The query that I have at the moment (which works based on key) is:
INSERT into table(recordnumber, username,type,course,status,started,completed) values('$data[0]','$data[1]','$data[2]','$data[3]','$data[4]','$data[5]','$data[6]')
ON DUPLICATE KEY UPDATE username='$data[1]',type='$data[2]',course='$data[3]',status='$data[4]',started='$data[5]',completed='$data[6]'
Any thoughts on how I could amend the query to get it to check based on username and course instead of duplicate key?
Thank you. :-)
The most correct way would be to create a unique index on username - course columns and use on duplicate key update.
Obviously, you can issue a select before the insert checking for existing record with same user name and course and issue an insert or an update as appropriate.
create a key on the username and course column and then use on duplicate key
CREATE TABLE test (
username varchar(255) NOT NULL,
course varchar(255),
num_entries INT DEFAULT 0,
UNIQUE KEY (username, course)
);
insert into test (username, course) values
('billybob', 'math'),
('billy', 'math'),
('billybob', 'math'),
('bob', 'math')
ON DUPLICATE KEY UPDATE num_entries = num_entries + 1;
this is a simple example, but you should understand what to do from here
SAMPLE FIDDLE
so putting this to work on your table
ALTER TABLE `courses` -- assuming the table is named courses
ADD CONSTRAINT `UK_COURSE_USERNAME` UNIQUE (username, course);
then your insert should just be the same as what you have
Example query in reference to my comment above.
IF EXISTS(SELECT id FROM Table WHERE username = '$data[1]' AND course <> '$data[3]')
(
UPDATE username='$data[1]',type='$data[2]',course='$data[3]',status='$data[4]',started='$data[5]',completed='$data[6]'
)
(
INSERT into table(recordnumber, username,type,course,status,started,completed) values('$data[0]','$data[1]','$data[2]','$data[3]','$data[4]','$data[5]','$data[6]')
)
You might use ON DUPLICATE KEY UPDATE if you added unique constraint for username and course value pair like this:
ALTER TABLE `table` ADD CONSTRAINT `UK_table_username_course` UNIQUE (username, course);
I have a query which updates the table or inserts if the row does not already exist, but for some reason it just inserts all the time.
This is my table structure:
Id (primary) | uid | product_id | quantity
This is my query:
INSERT INTO my_table (uid,product_id,quantity)
SELECT t1.uid,?,?
FROM checker t1
WHERE t1.id = ?
ON DUPLICATE KEY UPDATE
product_id = ?, quantity = quantity+?
What i want to do though is use on duplicate key if uid + product_id combination exist in the table already.
So is there a way to designate what kind of duplication to look for to update instead of insert?
There is no way to distinguish between what duplication occurs.
As soon as any unique constraint is violated - it will perform ON DUPLICATE KEY UPDATE part.
For your case you just need to create unique composite key that consists of 2 fields: (uid, product_id)
already searched for such topics and found 2 different solutions but noone works.
My table has structure | ID (auto_increment primary_key) | UID (int) | FAV_ID (int) |
I need to insert new record to this FAV_TABLE if UID and FAV_ID (both) already exist.
Example of my query:
INSERT INTO FAV_TABLE (uid, fav_id) VALUES ($u_id,$s_id) ON DUPLICATE KEY UPDATE uid = uid
or this one
INSERT IGNORE FAV_TABLE (uid, fav_id) VALUES ($u_id,$s_id);
As mysql manuals says this query doesn't add record only if PRIMARY_KEY is the same.
And I need query not to add record if pair uid+fav_id is unique.
Any solutions? Thank you
You need to add a UNIQUE KEY on those columns:
ALTER TABLE FAV_TABLE ADD UNIQUE KEY(uid, fav_id);
INSERT IGNORE or ON DUPLICATE KEY works only when a unique key is duplicated.
You need to add a UNIQUE index on both fields uid and fav_id.
That way, when you insert a duplicate pair, it will be ignored.
I created two tables and did the following:
Table 1: (students)
CREATE TABLE student(s int, n int, d int, PRIMARY KEY(s), FOREIGN KEY(d) REFERENCES dep(d));
Table 2: (dep)
CREATE TABLE dep(d int, n int, PRIMARY KEY(d));
So, if i understand correctly, d is a foreign key of table 1 and it references to the primary key of the department. Therefore, The primary key of dep have to match the d in students. However when I do the following
INSERT INTO dep (1,2);
The statement finished with no error? The students table is empty, how could the data be inserted when its primary key is referenced?
Please help, thanks.
By the way I was able to insert into student freely even dep does not have corresponding value. Do you guys think it's because of mysql vs. oracle?
mysql> select * from student;
+---+------+------+
| s | n | d |
+---+------+------+
| 5 | 5 | 5 |
+---+------+------+
1 row in set (0.00 sec)
mysql> select * from dep;
+---+------+
| d | n |
+---+------+
| 1 | 2 |
+---+------+
1 row in set (0.00 sec)
The student table has the foreign key d which is the primary key of the dep table. The student table is the one dependent on the dep table. The dep table has no such dependence on the student table. The constraint is on the student table to have a value of d that should always be in dep table.
Inserting a record into the student table with an invalid value for d WILL cause the error.
You've got your understanding the wrong way round. What you've done in your sql is ensure that when you enter a Student, the value for d must exist as a value in dep.d
if you said
insert into student values (1, 2, 3)
then this would fail if there was no row in dep with d equal to 3
You can insert into the department table as there is no constraint on this table.
If you will try to add a row in student table with the random department number , which is not present in the department table, then it will give you the constraint error.
Example :If you will try
insert into student values (1, 4, 1034);
And if there is no row in the department table with the value of primary key 1034 , then it will give the foreign key constraint.
What you need to do is insert your data starting from the parent down.
If you need to delete data you actually have to go the other way, delete the items before you delete the parent order record.
As usual, when you insert data into the detail table and master table has no corresponding values, you got an error - 'Cannot add or update a child row: a foreign key constraint fails...'.
But when the FOREIGN_KEY_CHECKS variable is set to 0, MySQL ignores foreign key constraints -
SET FOREIGN_KEY_CHECKS=0;
INSERT INTO student VALUES (5,5,5); -- no errors
SET FOREIGN_KEY_CHECKS=1;