Insert row only if it doesn't exist already in MySQL - mysql

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.

Related

mariaDB insert multiple rows where 2 cols not exists

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.

How to make multiple foreignkey value in 1 column?

how to make the output like this? From 4 tables (rate, cost, tools, car)
|`RateID` | `Costing` | `Toolsfk` and `CarFK` |
|---------------------------------------------|
| 1 | 1000 | 1004 |
| 2 | 2000 | 2003 |
this is the tables
i want to 2 or more Foreignkey in 1 column, should I use CONCAT? but, as I know, CONCAT is for output only. So, what if for output and input data in database? just use Insert?
polymorphic association is not possible, polymorphic association means single column has more than one foreign key for different tables. foreign key can target only one table at a time, a single column foreign key can't refer more than one tables, if u want to refer more than one table using single column then there are two ways..
1- creating identical table of referenced table
2- use two columns in a table, one column refer tools table and one column refer car table
below is a link from where you can take refrence
(Possible to do a MySQL foreign key to one of two possible tables?)

Is it possible to have a MySQL column containing multiple values as foreign keys?

I am learning MySQL and have MariaDB installed in Fedora 19.
I have a scenario where I require a column to contain multiple values in order to reduce possible redundancy of column allocation.
In the example below, is it possible to have each value in the tags column of the log table reference the tag_id column in the tags table?
users
user_id |
1 |
activities
activitity_id |
1
log
user_id | activity_id | tags
1 | 1 | 1,3,5 # multiple foreign keys?
tags
tag_id |
1 |
2 |
3 |
4 |
5 |
If it is not possible, could anyone provide the logic for the most feasible solution based on the data scenario above?
Similar Questions:
Are multiple foreign keys in a single field possible?
MySQL foreign key having multiple (conditional) possible values
it is possible to reference one column as multiple foreign keys
If you do not wish to make up a "middle man" table for linking the two tables you can have a comma separated value in the field, you would just need to use the find_in_set mysql function when doing queries
USING find_in_set
SELECT
log.user_id, log.activity_id, log.tags,
GROUP_CONCAT(tags.name) as taggedNames //This assumes there is a field called `name` in tags table
FROM
log
LEFT JOIN tags
ON
FIND_IN_SET(tags.tag_id,log.tags)
GROUP BY
log.activity_id
GROUP_CONCAT will group together a field and separate them by a deliminator, default is ,

Mysql Relational Database duplicate with different keys

I'm trying to correct a relational db for a month, but i cant find efficient solution.
Hier is my problem:
I have like 534 M rows Relational Db with lots of foreig keys(30).
I can handle normal duplicates with union...group by...havin count(*)=1 by inserting, but there are also duplciates with different keys.
example:
table 1
id | key1 | value
1 | 11 | a1
2 | 22 | a1
table 2
key1 | value
11 | a2
22 | a2
Foreign key table1(key1) references table2(key1)
I'm trying to find, remove duplicate , correct the parents.
I have tried 3 different ways,
1: PHP Script,Arrays
export tables (dump) --> array_unique, find duplicates, correct the parents array --> import tables
Its pretty fast, but need 80GB Memory, which could be problem in the future
2: PHP Script,SQL Query
exporrt tables(dump) --> find duplicates --> send queries to parent table
No need memory, but the tables are really big and 5 queries take 1 second, 50 M duplicates would take days, months, years
3: ON DUPLICATE UPDATE KEY: I added one column 'duplicate' to store duplicate keys and I defined all columns except key as unique key,
insert.... on duplicate update concat(duplicate,';',VALUES(key)).
But some tables has more than 1 key and sometimes I should define 24 column as unique index and memory problem again
I hope I could explain my problem. Do you have any idea ?
Why don't you simply create a unique key on column. Just use "Ignore" keyword it will remove the duplicate records.So your query will be something like: ALTER IGNORE TABLE testdb.table1
ADD UNIQUE INDEX column1 (column1 ASC) ;

Primary key on 2 tables

i have two tables, one 'master' and one 'child' table.
Each table has a field named 'ProductNo', which is defined as PRIMARY KEY and UNIQUE.
Is it possible to define the field 'ProductNo' in the table 'child' and the same field in table 'master' as PRIMARY + UNIQUE together?
master:
ID | ProductNo
child:
ID | MasterID (FK on master.ID) | ProductNo
Relation >> 1 (master) : n (child)
example data:
master:
1 | 1234
2 | 4567
child:
100 | 1 | 3333
101 | 1 | 4444
102 | 2 | 5555
103 | 1 | 1234 <----- NOT ALLOWED! PRODUCT NO ALREADY EXISTING IN TABLE `MASTER`
104 | 2 | 1234 <----- NOT ALLOWED! PRODUCT NO ALREADY EXISTING IN TABLE `MASTER`
It is needed to check on inserting/updating table 'child' if 'ProductNo' already exists in table 'master'.
How can I define it?
Or am I needed to create a trigger for this?
TIA Matt
no, there is no such thing as composite PKs among tables.
Just for data consistency, if the Ids are the same, you should add a FK from child to the master.
To solve your problem, a trigger with a check like this:
if exists (select 1 from master where prodcutId=new_productId)
would be a good idea
EDIT:
actually the best idea is to have only one table called product with a ID and a masterID field with a relation to itself. The way you have today Im pretty sure that you have a lot of duplicate data and you are stuck with 2 levels on hierarchy.
(Original answer) You can declare a foreign key from master to child, even if that foreign key points to the primary key of child. This would be a one to zero-or-one relationship, and is not that uncommon. A row cannot exist in child without a matching row in master already being inserted, but a row can exist in master without a matching child row. Your inserts therefore need to happen in the order master then child.
(Edited in light of question edit) HOWEVER, in your case, the column you are referring to looks like it should not actually be the primary key of either table, but rather you have a separate primary/foreign key, and the column in question needs to be unique across the two tables, which has become clear now you've edited some sample data into your question. In this case, you'd be best to use a trigger on both tables, to check existence in the other table and prevent the insert/update if the ProductNo already exists.
Just as #DavidM said, it can be done, but it seems you are with some modelling issues. First, if you have a natural primary key ProductNo, why do you define a surrogate ID? The other thing you might consider is to combine these two tables into a single one (as might make sense for most of 1-to-1 cases).
Are you sure you need the two tables?
Keep just one, having productID plus parentID.
Then productID can be a primary key and auto increment, while everything having a parentID other than null (f.keyed to the same table) would be a child item.
You can add a column named ProductNo in child table and add a foreign key reference to the parent table.