Delete single column from primary key in mysql - mysql

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.

Related

Unique Column in mysql database

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 (...);

Sql Statement: Insert On Key Update is not working as expected when primary key is not specified in the fields to insert

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.

MySQL on duplicate key on a non-unique field

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);

Mysql Insert on duplicated key with last_insert_id not working

create table test1 (
id int not null auto_increment primary key,
a varchar(16), b varchar(16)
);
INSERT INTO test1 (a,b) VALUES ('a1','b3') ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), b='3';
The above line should insert an entry since the table is empty.
INSERT INTO test1 (a,b) VALUES ('a1','b3') ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), b='3';
Run the line again, it should replace b with "3" since a1, b3 already exist. But mysql adds another line for me. I have searched awhile and can not find a solution.
Latest update: Thanks for all your help. I figured one of the column must be unique.
Alter table test1 add unique (a)
solve the problem.
The ON DUPLICATE is only triggered if the column has a UNIQUE KEY. Try adding a UNIQUE INDEX on your table on the a or b columns and it should work as intended.
There is no duplicate key in your case. Only unique column in your table is primary key id
Try
INSERT INTO test1 (id,a,b) VALUES (1,'a1','b3') ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), b='3';
twice.
First line of 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.
See the full documentation.

MySQL 'UPDATE ON DUPLICATE KEY' without a unique column?

What are peoples' thoughts on the most performance efficient way to do the following query:
3 column table
if the combination of col_1 and col_2 values already exist UPDATE col_3
else INSERT new row
I assume i need some kind if UPDATE ON DUPLICATE KEY (which i've never used before), however I do not have a 'KEY' but instead a pair of two values (columns) to make a key...
You can create a PRIMARY or UNIQUE key out of multiple columns (called a composite key) in MySQL, which'll allow ON DUPLICATE KEY to work just fine.
// create a composite index
CREATE INDEX my_composite_index ON my_table (column1, column2);
// insert or update
INSERT INTO my_table (column1, column2) VALUES ('value1', 'value2') ON DUPLICATE KEY UPDATE column3=column3+1;
Most efficient way is to create UNIQUE KEY and use ON DUPLICATE KEY UPDATE.
Slower way is to:
LOCK TABLE
SELECT TABLE (you need an index anyway for the best performance)
if exists, UPDATE
else INSERT
UNLOCK TABLES
Edit: Ignore my suggestions
You can use a composite key as ceejayoz said, however I think you need REPLACE INTO instead of UPDATE ON DUPLICATE KEY because REPLACE also inserts if no duplicate is found.
Note: I don't know the workings of UPDATE ON DUPLICATE KEY but it sounds like it doesn't perform inserts.