I have a databasw that has 2 columns.
First is category id, the second is group id.
Both are primary.
And i need to add to the table to the same category id some rows with group id 1 and 2.
I mean all the categories need to have groups 1,2,3
INSERT INTO `ps_category_group` (`id_category`, `id_group`)
SELECT `id_category`, 2 FROM (
SELECT DISTINCT `id_category`,`id_group` From `ps_category_group`) as x;
gives me
1062 - Duplicate entry '2-2' for key 'PRIMARY'
You are selecting values from the same table for inserting into the table. Then you are asking why you are getting primary key violations? Of course you are; that is exactly what your query is doing.
Based on the description, you seem to want:
INSERT INTO `ps_category_group` (`id_category`, `id_group`)
SELECT `id_category`, 2
FROM `ps_category_group`
ON DUPLICATE KEY UPDATE id_category = VALUES(id_category); -- This does nothing if the value already exists in the table
Related
I have the following query to append data into a table if it is unique:
INSERT INTO belgarath.players(tour_id, player_id, player_name_oc)
SELECT DISTINCT 0, ID_P, NAME_P FROM oncourt.players_atp
LEFT JOIN belgarath.players
ON belgarath.players.tour_id = 0
AND belgarath.players.player_id=oncourt.players_atp.ID_P;
I run this once on an empty table and it's fine. I delete a row and run it expecting MySQL to append the one deleted row. However, I get the following error code: Error Code: 1062. Duplicate entry '0-43042' for key 'players.unique_plyrs' . I have a unique key across tour_id and player_id and clearly it's failing because I'm trying to append a duplicate record.
Why would I be getting this if I'm only selecting distinct records to insert? How do I avoid getting this in future?
This should resolve your issue. Put a Where clause to check for belgarath.players.player_id is NULL.
INSERT INTO belgarath.players(tour_id, player_id, player_name_oc)
SELECT DISTINCT 0, ID_P, NAME_P FROM oncourt.players_atp
LEFT JOIN belgarath.players
ON belgarath.players.tour_id = 0
AND belgarath.players.player_id=oncourt.players_atp.ID_P
WHERE belgarath.players.player_id is NULL;
Hope this hint realted to Distinct keyword helps you. When we use distinct key it usually select distinct rows. So we can't expect it should return distinct values for only one column before which we have wrote distinct. Below example will better explain you what i am trying to say.
create table test(id1 int, id2 int);
insert into test values(1,1),(1,2),(1,3);
Here i have created a test table and when i use distinct keyword as used in below query
select distinct id1, id2 from test;
Then we'll get output like this:
id1 id2
1 1
1 2
1 3
You are inserting tour_ID as 0, and as you have defined tour_id and player_id as unique key in oncourt.players_atp table. So your select query is selecting tour_id as '0' every time. Because select query with distinct is getting really distinct records like say player_id is 1,2,3 and names are john, steve, bill respectively then select query will return this 3 records like (0, 1, john), (0, 2, steve), (0, 3, bill) and so on.
If your oncourt.players_atp table also has unique constraint and that table also contains tour_id then you can just copy tour ID from there. If tour_id is not present there and you want to generate it inside belgarath.players table only then in you table definition you can define tour id as a auto increment then it will generate unique id's there and then you don't need to select tour_id in your query you just have to insert player_id and player_name once you define tour_id as an autoincrement ID.
Hope this may help you.
I have the following many-to-many table:
id user_id comment_id like
1 1 1 true
2 1 2 false
3 2 1 true
4 2 2 true
I am trying to update a record if it exists (e.g. user_id = 1 AND comment_id = 1), otherwise create a new one. I cannot use unique key for user_id and comment_id columns because the same id can show up multiple times in this table. Is there any way of doing this with one query only?
Thanks,
According to your post, you should never have two rows for the same user_id and comment_id combination, making it an ideal candidate for a unique key:
ALTER TABLE mytable
ADD CONSTRAINT user_comment_unq UNIQUE (user_id, comment_id);
Once you have this constraint, you can use an insert statement with an on duplicate key update clause. E.g.:
INSERT INTO mytable (`user_id`, `comment_id`, `like`)
VALUES (1, 1, TRUE)
ON DUPLICATE KEY UPDATE `like` = TRUE
So I have an existing MySQL users table with thousands of records in it. I have noticed duplicate records for users which is a problem that I need to address. I know that the way I need to do this is to somehow make 2 columns unique.
The duplicates are arising with records containing both the same server_id column, and also the same user_id column. These 2 columns are meant to be unique combined. So there should only ever be 1 user_id per server_id.
I have figured out how I can find these duplicates using the following query:
SELECT `server_id`, `user_id`, COUNT(*) AS `duplicates` FROM `guild_users` GROUP BY `server_id`, `user_id` HAVING `duplicates` > 1
From what I have read, I need to delete all duplicates first before I add any constraints. This is one of the things I am unsure about.
Question 1: How would I go about deleting all duplicates, but leaving 1 of each so the user still exists, just not the other duplicates.
Question 2: What is the best way of avoiding duplicates from being created? Should I create a unique constraint for both of the columns, or do something with primary keys instead?
In your table there must exist a primary key column like an id.
So you can use EXISTS to delete the duplicates and keep just 1:
delete gu from guild_users gu
where exists (
select 1 from guild_users
where
server_id = gu.server_id
and
user_id = gu.user_id
and
id > gu.id
)
After that you can create a unique constraint for the 2 columns:
alter table guild_users
add constraint un_server_user unique
(server_id, user_id);
You want to prevent this by adding a unique index:
create unique index unq_guild_users_server_user on guild_users(server_id, user_id);
If you have a primary key, you can delete the duplicates before adding the unique index:
delete g
from guild_users g left join
(select server_id, user_id, max(primary_key) as max_pk
from guild_users
group by server_id, user_id
) su
on gu.primary_key = su.max_pk
where su.max_pk is null;
I have a problem with my queries in MySQL. My table has 4 columns and it looks something like this:
id_users id_product quantity date
1 2 1 2013
1 2 1 2013
2 2 1 2013
1 3 1 2013
id_users and id_product are foreign keys from different tables.
What I want is to delete just one row:
1 2 1 2013
Which appears twice, so I just want to delete it.
I've tried this query:
delete from orders where id_users = 1 and id_product = 2
But it will delete both of them (since they are duplicated). Any hints on solving this problem?
Add a limit to the delete query
delete from orders
where id_users = 1 and id_product = 2
limit 1
All tables should have a primary key (consisting of a single or multiple columns), duplicate rows doesn't make sense in a relational database. You can limit the number of delete rows using LIMIT though:
DELETE FROM orders WHERE id_users = 1 AND id_product = 2 LIMIT 1
But that just solves your current issue, you should definitely work on the bigger issue by defining primary keys.
You need to specify the number of rows which should be deleted. In your case (and I assume that you only want to keep one) this can be done like this:
DELETE FROM your_table WHERE id_users=1 AND id_product=2
LIMIT (SELECT COUNT(*)-1 FROM your_table WHERE id_users=1 AND id_product=2)
Best way to design table is add one temporary row as auto increment and keep as primary key. So we can avoid such above issues.
There are already answers for Deleting row by LIMIT. Ideally you should have primary key in your table. But if there is not.
I will give other ways:
By creating Unique index
I see id_users and id_product should be unique in your example.
ALTER IGNORE TABLE orders ADD UNIQUE INDEX unique_columns_index (id_users, id_product)
These will delete duplicate rows with same data.
But if you still get an error, even if you use IGNORE clause, try this:
ALTER TABLE orders ENGINE MyISAM;
ALTER IGNORE TABLE orders ADD UNIQUE INDEX unique_columns_index (id_users, id_product)
ALTER TABLE orders ENGINE InnoDB;
By creating table again
If there are multiple rows who have duplicate values, then you can also recreate table
RENAME TABLE `orders` TO `orders2`;
CREATE TABLE `orders`
SELECT * FROM `orders2` GROUP BY id_users, id_product;
You must add an id that auto-increment for each row, after that you can delet the row by its id.
so your table will have an unique id for each row and the id_user, id_product ecc...
I have a table which contains the items the users of my game owns. If a user buys a new item, it should be inserted, but if he already got it, it should be increased instead.
I understand I can use INSERT ... ON DUPLICATE KEY UPDATE, but I don't understand how in my problem.
The item_id isn't unique, because many players can own the same weapon (ie. a longsword). The user_id isn't unique either, because a player can own many items.
So, my question is how to make the query UPDATE instead of INSERT if a row containing both the user_id and item_id already exists?
I know this question is old but none of the answers are correct.
You need a PRIMARY or UNIQUE index on user_id and item_id (both columns in one index).
Then you can use "INSERT INTO ... VALUES ... ON DUPLICATE KEY UPDATE count=count+1" no problem.
This is EXACTLY what ON DUPLICATE UPDATE will do for you.
That's not what the "ON DUPLICATE KEY UPDATE" will do for you. If it were me, I would attempt the insert. If it failed, check why (you're checking for errors already, right?). If it's because of a duplicate key, do your update. If the error is for some other reason, then handle that appropriately.
You do want ON DUPLICATE KEY UPDATE. It looks for the Primary Key of the table, and if it exists, updates all the other rows.
So your table has a primary key of (userid, itemid) and the following values:
userid itemid strength
4 5 6
And you want to bump it to strength=9, use this:
INSERT INTO table ON DUPLICATE KEY UPDATE VALUES(4,5,9)
It will insert a row with 4,5,9 if it doesn't exist, and will update strength to 9 on the row with primary key (4,5) if it does exist. It won't update any other rows (e.g. rows with userid4 but itemid 10 or itemid 5 but userid 70) because they don't match the whole PK.
You could do something like the following (assumes your user id is in the variable UserID and item ID is in item_ID) :
SELECT
#rowCount := COUNT(*)
FROM
table
WHERE
user_id = UserID
AND item_id = ItemID;
IF (#rowCount > 0) THEN
... do update
ELSE
... do insert
END IF;
Can you do something like
UPDATE TABLE
set COL = 'BLAH BLAH'
where ITEM_ID = #itemid AND USER_ID = #userid
IF ##ROWCOUNT = 0
BEGIN
INSERT INTO TABLE (col...)
VALUES (vals...
END