I realize similar questions have been asked before, but I can't seem to find a solution that fits this particular scenario.
I would like to insert multiple rows of data into a mariaDB table where the data must be unique (primary key excluded).
Sample table:
enrollmentsID
classID
userID
1
1
2
2
1
3
3
1
4
4
2
2
5
2
7
So if I want to insert a number of rows, I don't want to duplicate what's already present.
The general idea is something like:
INSERT INTO `enrollments` (`enrollmentsID`, `classID`, `userID`)
VALUES (NULL,1,2),(NULL,1,3),(NULL,1,4),(NULL,1,5)
WHERE NOT EXISTS (
SELECT `enrollments`.`classID`, `enrollments`.`userID`
FROM `enrollments`)
Here, userID 5 would insert but userID 3 and userID 4 would be ignored.
Unfortunately, the WHERE is causing issues... Thanks for any help provided.
As P.Salmon mentioned in the comments, a UNIQUE index on the two columns is likely what you need. The index needs to be on both columns, not a UNIQUE index for each column.
ALTER TABLE enrollments
ADD UNIQUE INDEX (`classID`,`userID`)
From there you can do INSERT INGORE INTO instead of INSERT INTO and that will only insert the unique entries.
Related
I have a table table with two columns (idA and idB). The table assigns Bs to As, like this:
A | B
1 | 4
3 | 2
3 | 4
4 | 1
4 | 3 ...
So one A can have multiple Bs and thus shows up in more than one row. Hence, the table cannot have a primary key and I cannot use a unique column.
Is there a way to insert new rows only if an equal value pairing does not already exist, all in one query?
I tried REPLACE INTO and INSERT IGNORE INTO as mentioned here, but both seem to work for tables with primary keys only.
You can add a primary key! It just has to be over two columns and not just one.
ALTER TABLE your_table
ADD PRIMARY KEY(idA, idB)
That will make sure you only have unique records for both columns.
I have the tables:
Credit_account
==============
Acid int (PK)(AI)
Customer Id(Foreign Key ref Customer Table)
Credit Account char(15);
I want to insert record as
1 2 1-2
2 3 2-3
3 1 1-3
Is there any specific reason why you must use a select statement? Then there is some missing information.
If you have to use a select statement, it could be because the data from this table is from a JOIN. Else, you do not need multiple SELECT statements. An INSERT statement is sufficient.
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 wasn't sure how to explain this in the title, but what I have is a table like this:
user_id | subscription_id
6 12
6 10
12 6
4 12
Each user can subscribe to all other users, but is it possible to prevent a user from subscribing to another user twice through a INSERT query?
As my subscription_id is not unique, this happens:
user_id | subscription_id
6 12
6 12
And I want to avoid that. As far as I know INSERT IGNORE, INSERT UPDATE and ON DUPLICATE only works with unique keys.
You need to set up your database table to have a composite primary key for user_id AND subscription_id
That way each row has to be unique across both the columns.
See: How to properly create composite primary keys - MYSQL
The only reliable and easy way to make sure that a tuple cannot occur more than once inside a single table is either:
Use a spanning unique key
Use a spanning primary key
Maybe triggers
The first two are roughly the same, but unique keys treat null values as distinct as well, so that might not work for you.
ALTER TABLE user_subscriptions ADD PRIMARY(user_id, subscription_id);
Right now I have a table with an auto increment id number, a name, and a definition
I am updating the table with values from another table using
INSERT INTO words(id, word, definition) SELECT id, word, definition FROM temp
ON DUPLICATE KEY UPDATE words.word = temp.word, words.definition=temp.definition;
The table temp has the same exact column layout as the table I am using, and it works fine except when I delete an entry from the middle of temp and then update my main table.
For example,
temp
id word definition
1 bob is a cat
2 sam is a dog
3 doug is a monk
4 croe is a bird
table main is set to that
Then I remove row 2 from temp
temp
id word definition
1 bob is a cat
2 doug is a monk
3 croe is a bird
and then update main table
main
id word definition
1 bob is a cat
2 sam is a dog
3 croe is a bird
4 croe is a bird
because temp only has 3 rows now, but main HAD 4, the 4th row isn't deleted. I tried to fix this by making word a unique column, and now I get the error that there is a duplicate entry for key 'word'.
So how do I fix this?
From the MySQL manual,
In general, you should try to avoid using an ON DUPLICATE KEY UPDATE
clause on tables with multiple unique indexes.
so, what you could do is make word your primary key, and get rid of the id column. That should do the trick :)
Your query then becomes
INSERT INTO words(word, definition) SELECT word, definition FROM temp
ON DUPLICATE KEY UPDATE words.word = temp.word, words.definition=temp.definition;
If you need arbitrary sorting, I would create an additional table
CREATE TABLE word_order (VARCHAR(30) PRIMARY KEY, sort_order INT)
and then when you run your queries
SELECT words.word,
words.definition
FROM words
JOIN word_order
ON words.word = word_order.word
ORDER BY word_order.sort_order
Your INSERTS become a little more complicated though, you'd have to run multiple inserts. See sql - insert into multiple tables in one query.
Also, this CodeProject article has some more ideas on the topic.