How to make insert or delete? - mysql

Structure table:
id (int primary key)
name (varchar 100)
date(datetime)
For insert I use query:
INSERT INTO table (name, date) VALUES ('t1','$date');
For delete row I use query:
DELETE FROM table WHERE name = 't1';
I would like want how make 1 query: first insert, if row with it name already exist, than delete row, and insert again.
Tell me please how to make it?

Create a UNIQUE index over your name column:
ALTER TABLE `table` ADD UNIQUE (name);
If you genuinely want to "delete row and insert again", then you can use REPLACE instead of INSERT. As documented:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
Therefore, in your case:
REPLACE INTO `table` (name, date) VALUES ('t1','$date');
However, if instead of deleting the existing record and then inserting a new one you merely want to update the existing record, you can use INSERT ... ON DUPLICATE KEY UPDATE:
INSERT INTO `table` (name, date) VALUES ('t1','$date')
ON DUPLICATE KEY UPDATE date = VALUES(date);
The most material difference is in the treatment of columns for which you do not provide explicit values (such as id in your example): REPLACE will result in the new record having the default value, whereas INSERT ... ON DUPLICATE KEY UPDATE will result in the old value being retained.

What you want to do is use MySQL's on duplicate update feature.
Can be used like this :
INSERT INTO table (name, date) VALUES ('t1','$date')
ON DUPLICATE KEY UPDATE name=VALUES(name),dateVALUES(date);
Of course for that to happen a dupliate violation must occur.

insert into table (name, date) values('t1','$date') on duplicate key update name=values(name), date=values(date)

Are you looking for an update query?
Update will set a value on an already existing row.
UPDATE table SET date = '$newdate' WHERE name = 't1';

The best way to do this is using the mysql methods together with your query.
If you make the 'name' field unique:
id (int primary key)
name (varchar 100) NOT NULL UNIQUE
date(datetime)
And alter the query to:
INSERT INTO table
(name, date) VALUES ('t1','$date')
ON DUPLICATE KEY UPDATE date = "$date"

Related

MySQL: How To Add IF EXISTS Then UPDATE Else INSERT? [duplicate]

UPDATE AggregatedData SET datenum="734152.979166667",
Timestamp="2010-01-14 23:30:00.000" WHERE datenum="734152.979166667";
It works if the datenum exists, but I want to insert this data as a new row if the datenum does not exist.
UPDATE
the datenum is unique but that's not the primary key
Jai is correct that you should use INSERT ... ON DUPLICATE KEY UPDATE.
Note that you do not need to include datenum in the update clause since it's the unique key, so it should not change. You do need to include all of the other columns from your table. You can use the VALUES() function to make sure the proper values are used when updating the other columns.
Here is your update re-written using the proper INSERT ... ON DUPLICATE KEY UPDATE syntax for MySQL:
INSERT INTO AggregatedData (datenum,Timestamp)
VALUES ("734152.979166667","2010-01-14 23:30:00.000")
ON DUPLICATE KEY UPDATE
Timestamp=VALUES(Timestamp)
Try using this:
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index orPRIMARY KEY, MySQL performs an [UPDATE`](http://dev.mysql.com/doc/refman/5.7/en/update.html) of the old row...
The ON DUPLICATE KEY UPDATE clause can contain multiple column assignments, separated by commas.
With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values. If you specify the CLIENT_FOUND_ROWS flag to mysql_real_connect() when connecting to mysqld, the affected-rows value is 1 (not 0) if an existing row is set to its current values...
This is not too bad, but we could actually combine everything into one query. I found different solutions on the internet. The simplest, but MySQL only solution is this:
INSERT INTO wp_postmeta (post_id, meta_key)
SELECT
?id,
‘page_title’
FROM
DUAL
WHERE
NOT EXISTS (
SELECT
meta_id
FROM
wp_postmeta
WHERE
post_id = ?id
AND meta_key = ‘page_title’
);
UPDATE
wp_postmeta
SET
meta_value = ?page_title
WHERE
post_id = ?id
AND meta_key = ‘page_title’;
Link to documentation.
I had a situation where I needed to update or insert on a table according to two fields (both foreign keys) on which I couldn't set a UNIQUE constraint (so INSERT ... ON DUPLICATE KEY UPDATE won't work). Here's what I ended up using:
replace into last_recogs (id, hasher_id, hash_id, last_recog)
select l.* from
(select id, hasher_id, hash_id, [new_value] from last_recogs
where hasher_id in (select id from hashers where name=[hasher_name])
and hash_id in (select id from hashes where name=[hash_name])
union
select 0, m.id, h.id, [new_value]
from hashers m cross join hashes h
where m.name=[hasher_name]
and h.name=[hash_name]) l
limit 1;
This example is cribbed from one of my databases, with the input parameters (two names and a number) replaced with [hasher_name], [hash_name], and [new_value]. The nested SELECT...LIMIT 1 pulls the first of either the existing record or a new record (last_recogs.id is an autoincrement primary key) and uses that as the value input into the REPLACE INTO.

IF NOT EXISTS then INSERT

I'm trying to add a value to a table but not without checking if the value already exists. This is what I have so far:
IF NOT EXISTS (
SELECT series.seriesName
FROM series
WHERE series.seriesName='Avengers'
)
BEGIN
INSERT INTO series (seriesName) VALUES 'Avengers'
END;
Database is a MySQL db on Ubuntu
You can use IGNORE keyword here.
It could look like:
INSERT IGNORE INTO series (seriesName) VALUES 'Avengers'
The important thing is to create a unique key on seriesName field as it seems that you want it to be unique.
INSERT IGNORE doesn't make the insert when key value already exists.
If you would like to be able to get id (primary key value) for row that wasn't inserted (already existed), you can do the following trick:
INSERT IGNORE INTO series (seriesName) VALUES 'Avengers'
ON DUPLICATE KEY UPDATE seriesID= LAST_INSERT_ID(seriesID)
Then you will be able to get the ID with LAST_INSERT_ID() function no matter if the row was inserted or not.

Detect if MySQL has duplicates when inserting

I have a table with the columns value1, value2 and value3.
Every few months, all rows will need to change their 'value1' to a different value. So far I have the following code and I cannot figure out for the life of me why it is not working. Instead of only modifying column one, it generates an entire new row of information.
Thanks in advance.
INSERT INTO table (value1, value2, value3)
VALUES ('$valueForValue1', '$valueForValue2','$valueForValue3')
ON DUPLICATE KEY UPDATE
`value1`='$valueForValue1',
`value2`='$valueForValue2',
`value3`='$valueForValue3',
In order to be able to change a value of value1 with ON DUPLICATE KEY clause you have to have either a UNIQUE constraint or a PRIMARY KEY on (value2, value3).
ALTER TABLE table1 ADD UNIQUE (value2, value3);
Now to simplify your insert statement you can also use VALUES() in ON DUPLICATE KEY like this
INSERT INTO Table1 (`value1`, `value2`, `value3`)
VALUES ('$valueForValue1', '$valueForValue2', '$valueForValue3')
ON DUPLICATE KEY UPDATE value1 = VALUES(value1);
Here is SQLFIddle demo
The UPDATE action of the ON DUPLICATE KEY clause will only be executed if the row being inserted would cause the violation of a UNIQUE constraint. That means there needs to be a primary key or a unique index on the table.
If you want to modify existing rows, you'd really want to use an UPDATE statement.
To change the value in a column of existing rows, replacing 'oldvalue' with 'newvalue', you could do something like this:
UPDATE mytable
SET col1 = 'newvalue'
WHERE col1 = 'oldvalue'

inserting new rows to table without updating old ones

Alright, i have revised the question to also include what i have so far, and what i want to do. So here goes it:
CREATE ORDER (
product_nat_id int(3) NOT NULL,
name VARCHAR(20),
PRIMARY KEY (product_nate_id)
)
INSERT INTO ORDER(product_nat_id, name) VALUES(1, 'Product 1');
INSERT INTO ORDER(product_nat_id, name) VALUES(2, 'Product 2');
INSERT INTO ORDER(product_nat_id, name) VALUES(3, 'Product 3');
CREATE TABLE INT_PRODUCT (
product_id INTEGER NOT NULL AUTO_INCREMENT,
product_nat_id INTEGER NOT NULL,
title TINYTEXT,
dateCreate TIMESTAMP CURRENT_TIMESTAMP,
CONSTRAINT INT_PRODUCT_PK PRIMARY KEY (product_id),
UNIQUE INT_PRODUCT_NK (product_nat_id));
But what i want is, whenever a record arrives with an updated value but duplicate key, i need to insert it (and not updated), but avoid duplicate constraint based on the difference in time inserted. Hope this makes sense now.
I would suggest the following:
Look up the previous record. I assume you should know what that would be
SELECT Count(*) FROM dim WHERE recordId = '$recordid'
If in step 1 the records returned are larger than 0 then invalidate the 'previous' record:
UPDATE dim SET datevalid = '$datevalue' where recordId = '$recordid' and status = 2
Continuing with step 1 where the ecords return in the check are larger than 0 now do the insert:
INSERT INTO dim (recordId,field1,field2,date,status) VALUES (1,'sad','123123','2013-03-26',1)
If step 1 was false then just do the insert:
INSERT INTO dim (recordId,field1,field2,date,status) VALUES (1,'sad','123123','2013-03-26',1)
I would add a status field just as an extra measure when you need to find records and distinguish between valid or invalid then you do not need to filter between dates. You can then use the status field. Also have a unique auto-increment key for every record even though the data might be the same for a set of valid and invalid records. recordId and unique key will not be the same in this case. You assign the recordId and the system will assign the unique key on the table. status = 1 is valid and status = 2 is invalid.
Hope this helps!
sample code of your post like as:
Insert query syntax looks like this:
INSERT INTO table (primarykeycol,col1,col2)
VALUES (1,2,3) ON DUPLICATE KEY UPDATE col1=0, col2=col2+1
If there is already a row with primarykeycol set to 1 this query is equal to:
UPDATE table SET col1=0, col2=col2+1 WHERE primarykeycol = 1
explanation as:
Ordinarily to achieve the same result you would have to issue an
UPDATE query, then check if there were affected rows and if not
issue an INSERT query.
This way, you can do everything in one step – first try insert and
then update if insert fails.
One situation for which this type of syntax is perfect is when you
work with daily counters. For example, you might have a table with
PostID, Date and Count columns.
Each day you’d have to check if you already created an entry for
that day and if so increase the count column – and this can be
easily substituted with one INSERT … ON DUPLICATE KEY UPDATE query.
Unfortunately there are some caveats. One being that when you have
multiple unique indexes it will act as if you had an OR condition in
WHERE clause of UPDATE query.
This means that multiple rows should be update, but INSERT … ON
DUPLICATE KEY UPDATE will update only one row.
MySQL manual: INSERT ON DUPLICATE KEY UPDATE Syntax

MySql Table Insert if not exist otherwise update

UPDATE AggregatedData SET datenum="734152.979166667",
Timestamp="2010-01-14 23:30:00.000" WHERE datenum="734152.979166667";
It works if the datenum exists, but I want to insert this data as a new row if the datenum does not exist.
UPDATE
the datenum is unique but that's not the primary key
Jai is correct that you should use INSERT ... ON DUPLICATE KEY UPDATE.
Note that you do not need to include datenum in the update clause since it's the unique key, so it should not change. You do need to include all of the other columns from your table. You can use the VALUES() function to make sure the proper values are used when updating the other columns.
Here is your update re-written using the proper INSERT ... ON DUPLICATE KEY UPDATE syntax for MySQL:
INSERT INTO AggregatedData (datenum,Timestamp)
VALUES ("734152.979166667","2010-01-14 23:30:00.000")
ON DUPLICATE KEY UPDATE
Timestamp=VALUES(Timestamp)
Try using this:
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index orPRIMARY KEY, MySQL performs an [UPDATE`](http://dev.mysql.com/doc/refman/5.7/en/update.html) of the old row...
The ON DUPLICATE KEY UPDATE clause can contain multiple column assignments, separated by commas.
With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values. If you specify the CLIENT_FOUND_ROWS flag to mysql_real_connect() when connecting to mysqld, the affected-rows value is 1 (not 0) if an existing row is set to its current values...
This is not too bad, but we could actually combine everything into one query. I found different solutions on the internet. The simplest, but MySQL only solution is this:
INSERT INTO wp_postmeta (post_id, meta_key)
SELECT
?id,
‘page_title’
FROM
DUAL
WHERE
NOT EXISTS (
SELECT
meta_id
FROM
wp_postmeta
WHERE
post_id = ?id
AND meta_key = ‘page_title’
);
UPDATE
wp_postmeta
SET
meta_value = ?page_title
WHERE
post_id = ?id
AND meta_key = ‘page_title’;
Link to documentation.
I had a situation where I needed to update or insert on a table according to two fields (both foreign keys) on which I couldn't set a UNIQUE constraint (so INSERT ... ON DUPLICATE KEY UPDATE won't work). Here's what I ended up using:
replace into last_recogs (id, hasher_id, hash_id, last_recog)
select l.* from
(select id, hasher_id, hash_id, [new_value] from last_recogs
where hasher_id in (select id from hashers where name=[hasher_name])
and hash_id in (select id from hashes where name=[hash_name])
union
select 0, m.id, h.id, [new_value]
from hashers m cross join hashes h
where m.name=[hasher_name]
and h.name=[hash_name]) l
limit 1;
This example is cribbed from one of my databases, with the input parameters (two names and a number) replaced with [hasher_name], [hash_name], and [new_value]. The nested SELECT...LIMIT 1 pulls the first of either the existing record or a new record (last_recogs.id is an autoincrement primary key) and uses that as the value input into the REPLACE INTO.