INSERT INTO if NOT EXISTS or increment if EXISTS - mysql

My question is. I have the table 'popular' with fields 'id', 'title', 'popularity' in MySQL. I need insert info into field "title", if info not exists or increment value of 'popularity', if info exists. What is the best practice to do it?

INSERT ... ON DUPLICATE KEY UPDATE Syntax

INSERT INTO popular (title, popularity) VALUES (:the_title, 1)
ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id), popularity = popularity + 1
Make sure you have an unique constraint on title
id = LAST_INSERT_ID(id) allows you to get the id of the record you inserted/updated using LAST_INSERT_ID (or the equivalent function for your MySQL API). If you don't need the id you can remove it from the UPDATE list.

sample code:
if exists (select * from contact where name = #name) then
select -1;
else
insert into contact(name) values(#name);
select last_insert_id();
end if;
reference:
http://ask.sqlservercentral.com/questions/88038/best-mysql-practice-to-insert-a-record-if-it-does.html
http://bugs.mysql.com/bug.php?id=19243
http://mikefenwick.com/blog/insert-into-database-or-return-id-of-duplicate-row-in-mysql/

Related

Update if row > 0 OR INSERT on Mysql

How to I can create a query for update, if select result is bigger then 0, else execute insert?
I had try execute this code, but is not work
select
case
where count(id) > 0 (update product set description = 'blablabla' where id_fk1 = 3 AND id_fk2 = 4)
else (insert into product (description) values('blablabla')
end
I know this is a select code, it will not work, but I don't know how to use If in mysql
you can use this example foreign-keys
there is a way to compose single query which compose single query with 'update ...' and 'insert into...'
or, if i misunderstood you, you can use this one insert-on-duplucate
What you need is INSERT with ON DUPLICATE KEY UPDATE clause:
https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
This has been asked before:
Insert into a MySQL table or update if exists
Contains many interesting answers.
Presumably, you want to insert the paid id = 3, description = 'blablabla' into the table. If it exists, then update the description.
You can use insert . . . on duplicate key insert, assuming that id is declared as the primary key or as a unique key. You would do this as:
create unique key product_id on product(id);
Then the following statement does what you want:
insert into product(id, description)
select 3, 'blablabla'
on duplicate key insert description = values(description);
EDIT:
I think the same idea applies to two foreign keys:
create unique key product_fk1_fk2 on product(id_fk1, id_fk2);
insert into product(id_fk1, id_fk2, description)
select 3, 4, 'blablabla'
on duplicate key insert description = values(description);
It will be base on the number of your query result, right?
$result=mysqli_query($con,"SELECT * FROM product");
if(mysqli_num_rows($result)==0){
mysqli_query($con,"INSERT INTO product (description) VALUES ('blah')");
}
else {
mysqli_query($con,"UPDATE product SET description='blah'");
}
If you're trying to base it on your id field, try this:
$result=mysqli_query($con,"SELECT * FROM product");
if(mysqli_num_rows($result)==0){
mysqli_query($con,"INSERT INTO product (description) VALUES ('blah')");
}
else
while($row=mysqli_fetch_array($result)){
$id=$row['id'];
if($id>0){
mysqli_query($con,"UPDATE product SET description='blah' WHERE id='$id'");
}
} /* END OF WHILE LOOP */
} /* END OF ELSE */

Insert a record only if it is not present

I need to create a query to insert some records, the record must be unique. If it exists I need the recorded ID else if it doesnt exist I want insert it and get the new ID. I wrote that query but it doesnt work.
SELECT id FROM tags WHERE slug = 'category_x'
WHERE NO EXISTS (INSERT INTO tags('name', 'slug') VALUES('Category X','category_x'));
It's called UPSERT (i.e. UPdate or inSERT).
INSERT INTO tags
('name', 'slug')
VALUES('Category X','category_x')
ON DUPLICATE KEY UPDATE
'slug' = 'category_x'
MySql Reference: 13.2.5.3. INSERT ... ON DUPLICATE KEY UPDATE Syntax
Try something like...
IF (NOT EXISTS (SELECT id FROM tags WHERE slug = 'category_x'))
BEGIN
INSERT INTO tags('name', 'slug') VALUES('Category X','category_x');
END
ELSE
BEGIN
SELECT id FROM tags WHERE slug = 'category_x'
END
But you can leave the ELSE part and SELECT the id, this way the query will always return the id, irrespective of the insert...
MySQL has nice REPLACE. It is easy to use and remember it's syntax as same as INSERT.
in you case, just run following query.
REPLACE INTO tags('name', 'slug') VALUES('Category X','category_x')
It acts like INSERT when no unique constraint violation. If duplicated value found on PK or UNIQUE key, then other columns will be UPDATED with given values. It is done by DELETE duplicated record and INSERT new record.

Why is this MySQL query causing an error?

Query:
INSERT INTO `metadata` (`group_id`, `key`, `value`)
VALUES ("19", "originality", "2")
ON DUPLICATE KEY UPDATE (`group_id` = `19`, `key`=`originality`, `value`=`2`)
The table:
group_id | key | value
----------------------------------------
group_id and key both have a UNIQUE index.
The error happens when I try to run the query when a row already exists with the id 19. The way I want the query to function is, if there is no row with that id, insert it and if there is update it instead of inserting a new row.
The error message I get is the typical:
I'm not sure if a ( should follow the UPDATE keyword - I think not. So try
ON DUPLICATE KEY UPDATE `group_id` = 19, `key`='originality', `value`=2
(or replace group_id with submission_group_id - your error message doesn't seem to match the original query)
you can only use ` on table columns and table names, not for data.
data should use ' or "
like:
ON DUPLICATE KEY UPDATE `group_id` = 19, `key`="originality", `value`=2
The quote tag must be the ' character not the ` character.
if there is no row with that id, insert it and if there is update it instead of inserting a new row.
If you want to do this you should try statement like:
IF EXISTS (SELECT * FROM sometable WHERE ColumnName='somevalue')
UPDATE sometable SET (...) WHERE ColumnName='somevalue'
ELSE
INSERT INTO Table1 VALUES (...)

mysql insert if not exists on joined tables

My tables look like this:
Table "posts"
posts.id = PK, auto-increment
posts.text = varchar
posts.tag_id 1 = int, FK to tags.id
posts.tag_id 2 = int, FK to tags.id
posts.tag_id 3 = int, FK to tags.id
Table "tags"
tags.id = PK, auto-increment
tags.tag = varchar
Now I want to insert the following data:
text: 'lorem ipsum'
tag1: 'music'
tag2: 'pop'
tag3: 'singer'
So I need a query that checks if tag1/tag2/tag3 already exist in "tags", inserts them otherwise and then insert those as foreign-keys + the "text" into a new row in "posts".
I had a look into mysql INSERT IF NOT EXISTS but I'm just stuck and don't know where to start. I know I could handle it with multiple queries but there has to be another, lighter way to achieve the same result.
Has anyone any experience with this?
Update
A friend of mine proposed something like this:
CREATE FUNCTION getTagID(tag VARCHAR('100')) RETURNS int
INSERT INTO posts (text,tag1,tag2,tag3)
VALUES ('lorem ipsum', getTagID('music'), getTagID('pop'), getTagID('singer'));
Of course the implementation of getTagId is still missing, but does that make sense? getTagID should select the id with the given tag, if it doesn't exist, insert it and return this. Any help is appreciated.
Solution
I created a custom function in MySql:
DELIMITER ;;
CREATE FUNCTION getTagID(tag VARCHAR(100)) RETURNS BIGINT
BEGIN
DECLARE tagID BIGINT;
SET tagID = (SELECT id FROM tags WHERE text = tag);
IF tagID IS NULL
THEN
INSERT INTO tags (text) VALUES (tag);
SET tagID = (SELECT LAST_INSERT_ID());
END IF;
RETURN tagID;
END;;
DELIMITER ;
and now I can just insert into posts like that:
INSERT INTO posts (text,tag1,tag2,tag3)
VALUES ('lorem ipsum', getTagID('music'), getTagID('pop'), getTagID('singer'));
with that function, which inserts into "tags" only if the tag does not yet exist and gives back the ID of the existing or newly created tag. Yipeee :)
You have to insert to posts, then insert to tags. There is no multi-table insert solution in SQL.
You can't even insert the post text to posts from a trigger on tags, because the insert to tags can only carry columns that belong to tags.
You can use INSERT IGNORE or REPLACE or INSERT ... ON DUPLICATE KEY UPDATE if you need to avoid duplicates in the tags table. See my answer to "INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE" for more details on that.
Re your comment.
You can get the generated PK only if you let the auto-increment mechanism generate a new id. If you let auto-increment happen, you're guaranteed not to result in a duplicate PK.
If you specify an id and bypass auto-increment, you can't get the id anyway. But you don't need to query for the value if you specified it in your INSERT -- you should have it already.
The only other case is if you have a secondary unique key that's not auto-increment.
CREATE TABLE foo (id int auto_increment primary key, name varchar(10), unique key (name));
INSERT INTO foo (name) VALUES ('bill');
SELECT LAST_INSERT_ID(); -- returns 1
INSERT INTO foo (name) VALUES ('bill');
SELECT LAST_INSERT_ID(); -- returns 1
This is slightly confusing because the last insert id comes from the last INSERT that succeeded and generated an id.
Re your update with INSERT INTO posts (text,tag1,tag2,tag3). That's called repeating groups. What if you need four tags? What if a post has only two tags? How do you make an indexed search for posts with a given tag?

MYSQL trigger see if record exists first?

So I have a trigger that works on update. Totally works fine.
Insert in cars(date, id, parent_id) values (date, ford, 2)
What I need to do is to actually check to see if the parent_id already exists. If it does do nothing but if it does not exist then do the insert statement.
right now i have
SET #myVar1 = (SELECT parent_id from cars where parent_id = NEW.id);
IF #myVar1 = NULL;
Insert in cars(date, id, parent_id) values (date, ford, 2);
ENDIF;
I keep getting sysntax error. How am I writing this worng?
The problem is on this line:
Insert in cars(date, id, parent_id) values (date, ford, 2);
The in should be INTO. That's the syntax error.
That said, you might be better served with an INSERT...ON DUPLICATE KEY or REPLACE INTO statement rather than an on-update trigger. Be careful with REPLACE INTO though, as it can be dangerous (but the danger can be somewhat mitigated by using transactions).
dunno if this what you really need. but you can try this one
SET #myVar1 = (SELECT parent_id from cars where parent_id = NEW.id);
IF (#myVar1 is NULL) then
Insert into cars(`date`, id, parent_id) values (date(), new.`name`, new.id);
END IF;
or
Insert into cars(`date`, id, parent_id) values (date(), new.`name`, new.id) on duplicate key update `date`=date();
on mysql must be "end if" not "endif".
new.name is assumes that id field on car from trigger table
you can use on duplicate key update if cars table use primary key or unique key like mention above
and if you doesn't want to change any record if exists then after key update change to id=id or you can use any field.