I have a table containing all sort of parameters.
The structure of the table is : id, object_id, param_name, param_value
The following code works, but it appends results instead of updating them.
The fact is that I can't use ON DUPLICATE KEY because my fields are non-uniques (except for id of course)
INSERT INTO `params_table` (`object_id`, `param_name`, `param_value`)
SELECT
A.id AS my_object_id,
'XYZ' AS my_param_name,
IF(TMP.abc IS NULL,0,1) AS my_param_value
FROM
ref_table AS A
LEFT JOIN tmp_table AS TMP ON TMP.abc = A.abc
ON DUPLICATE KEY
UPDATE `param_value` = IF(TMP.abc IS NULL,0,1);
The ON DUPLICATE KEY clause does not only work on the primary key:
If you specify ON DUPLICATE KEY
UPDATE, and a row is inserted that
would cause a duplicate value in a
UNIQUE index or PRIMARY KEY, an UPDATE
of the old row is performed
So unless I'm missing something obvious you simply need to create a unique index on the column combination you want to make unique:
ALTER TABLE params_table
ADD UNIQUE unique_object_param(object_id,param_name);
Related
I m facing a probem and i don't believe that it can accept a solution so I hope if anyone knows a solution suggest it, please.
I have a column in my table that contains a certain records; some of those records are duplicated and I want to insert some new records into my table, but I wish for the new records to not be duplicated. So, basically I want to control when the data can be duplicated and when not.
I ve tried this but it does not work:
ALTER TABLE MyTable DROP PRIMARY KEY
ALTER TABLE MyTable
ADD PRIMARY KEY (`S.No`),
ADD UNIQUE KEY `PCID_uk` (`PCID`),
ADD UNIQUE KEY `USERNAME_uk` (`USERNAME`)
some of those records are duplicated and I want to insert some new records into my table, but I wish for the new records to not be duplicated
Constraints are meant to guarantee integrity over the whole table, so what you ask for is not not straight forward, but still possible.
The idea is to create a new column with a default value of 1, and then feed it using row_number() (available in MySQL 8.0). Assuming that the primary key of your table is id, and that you want to enforce partial uniqueness on column col, that would look like:
alter table mytable add col_rn int default 1;
update mytable t
inner join (
select id, row_number() over(partition by col order by id) rn
from mytable
) t1 on t1.id = t.id
set t.col_rn = t.rn;
With this set up at hand, you can create the following unique constraint
alter table mytable add constraint unique_col_rn unique (col, col_rn);
Now you can insert new records in your table, not providing values for col_rn, so it defaults to 1. If a record already exists for col, the unique constraint raises an error.
insert into mytable (col) values (...);
Hello I am using the "INSERT ON DUPLICATE KEY UPDATE" sql statement to update my database.
All was working fine since I always inserted an unique id like this:
INSERT INTO devices(uniqueId,name)
VALUES (4,'Printer')
ON DUPLICATE KEY UPDATE name = 'Central Printer';
But for now, I need to insert elements but I don't insert a unique id, I only insert or update the values like this:
INSERT INTO table (a,b,c,d,e,f,g)
VALUES (2,3,4,5,6,7,8)
ON DUPLICATE KEY
UPDATE a=a, b=b, c=c, d=d, e=e, f=f, g=g;
Have to say that an autoincrement primary key is generated always that I insert a row.
My problem is that now the inserted rows are duplicated since I don't insert the primary key or unique id explicitly within the sql statement.
What I am supposed to do?
For example, maybe I need to insert the primary key explicitly? I would like to work with this primary autoincremented key.
For recommendation from Gordon I am adding a sample case the you can see in the next image
Rows Output
In this case I add the first three rows, and then I try to update the three first rows again with different information.... Ok I am seeing the error... There is no key to compare to...... :$
Thanks for your answers,
If you want to prevent columns from being duplicated, then create a unique index or constraint on them. For instance:
create unique index unq_table_7 on table(a, b, c, d, e, f, g);
This will guarantee that the 7 columns -- in combination -- are unique.
I have a table with a primary key that consists of 5 columns. I found out that one of these columns should not be in the primary key because it is creating duplicates. I'm trying and failing at removing this column (both from the primary key and just entirely from the table).
Initially I just used MySQL Workbench to unselect the column as PK and just clicked Apply. The workbench generates this SQL:
ALTER TABLE `mydb`.`mytable`
DROP PRIMARY KEY,
ADD PRIMARY KEY (`column1`, `column2`, `column3`, `column4`);
This causes the following error:
ERROR 1062: Duplicate entry '624634475-17-2-19000' for key 'PRIMARY'
I'm guessing that the database doesn't like the existence of duplicate entries. So I did some searching on how to delete duplicates and found this:
ALTER IGNORE TABLE mytable ADD UNIQUE (column1, column2, column3, column4)
This query also fails with an error:
Error Code: 1062. Duplicate entry '624634475-17-2-19000' for key 'column1'
I don't care which duplicate survives, I just want my primary key to be correct and to have some data left over at the end.
I found a solution. You can delete records from a table by comparing the records to each other in this way:
DELETE t FROM table t, table u WHERE t.column2 < u.column2 AND t.column1 = u.column1 AND t.column3 = u.column3 AND t.column4 = u.column4 AND t.column5 = u.column5;
In this query column2 is the one I want to delete while the other 4 columns are the ones I want to keep in the primary key. All records that are equal in the new definition will be deleted except for one.
Once done I was able to successfully run the original ALTER statement.
I don't care which duplicate survives, I just want my primary key to
be correct
If your new PK consists of columns 1 through 4, and columns 1 through 5 are unique at the moment, you can can use
SELECT column1, column2, column3, column4, MIN(column5)
FROM mytable
GROUP BY column1, column2, column3, column4
to get exactly one record for each unique combination of columns 1...4.
Then you can go ahead and delete all records from mytable where the (old) PK does not match the values selected above.
After that, columns 1...4 will be unique and you can re-create your PK constraint.
I've been reading up on how to use MySQL insert on duplicate key to see if it will allow me to avoid Selecting a row, checking if it exists, and then either inserting or updating. As I've read the documentation however, there is one area that confuses me. This is what the documentation says:
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, an UPDATE of the old row is performed
The thing is, I don't want to know if this will work for my problem, because the 'condition' I have for not inserting a new one is the existence of a row that has two columns equal to a certain value, not necessarily that the primary key is the same. Right now the syntax I'm imagining is this, but I don't know if it will always insert instead of replace:
INSERT INTO attendance (event_id, user_id, status) VALUES(some_event_number, some_user_id, some_status) ON DUPLICATE KEY UPDATE status=1
The thing is, event_id and user_id aren't primary keys, but if a row in the table 'attendance' already has those columns with those values, I just want to update it. Otherwise I would like to insert it. Is this even possible with ON DUPLICATE? If not, what other method might I use?
The quote includes "a duplicate value in a UNIQUE index". So, your values do not need to be the primary key:
create unique index attendance_eventid_userid on attendance(event_id, user_id);
Presumably, you want to update the existing record because you don't want duplicates. If you want duplicates sometimes, but not for this particular insert, then you will need another method.
If I were you, I would make a primary key out of event_id and user_id. That will make this extremely easy with ON DUPLICATE.
SQLFiddle
create table attendance (
event_id int,
user_id int,
status varchar(100),
primary key(event_id, user_id)
);
Then with ease:
insert into attendance (event_id, user_id, status) values(some_event_number, some_user_id, some_status)
on duplicate key
update status = values(status);
Maybe you can try to write a trigger that checks if the pair (event_id, user_id) exists in the table before inserting, and if it exists just update it.
To the broader question of "Will INSERT ... ON DUPLICATE respect a UK even if the PK changes", the answer is yes: SQLFiddle
In this SQLFiddle I insert a new record, with a new PK id, but its values would violate the UK. It performs the ON DUPLICATE and the original PK id is preserved, but the non-UK ON DUPLICATE KEY UPDATE value changes.
I have the table with following structure
id -- auto increment
name -- unique
group -- integer
Primary key(name,group)
I do not want to add the element with the same name and group values.
(i.e ("test",1) and ("test",1) should not be inserted.... and
("test",1),("test",2) can be inserted).
I want to insert a value if not exist .. I checked the Link.
Using the above link it is possible to do the operation , but the problem is it only checks the name as key not combined with group (i.e Insertion of the values("test",1) and ("test",2) is not happening)
How can i do this.
I think problem with name column unique ,please remove unique constraint on name column and try INSERT IGNORE INTO yourTable(name,group)values("test",2)
If your primary key is a composite of name and group
You can do INSERT IGNORE
INSERT IGNORE INTO yourTable
SET name = 'test',
group = 1;
As long as both of them are part of your primary key, this should check for their combination