On duplicate key ignore - Update multiple tables - mysql

I am attempting to insert data into two tables (table1 and table2), conditional on the uniqueness of the data being entered into table1. Table1 has a unique key set on pop & email & neighborhood. The idea is that if the same person submits the same pop in a neighborhood, then nothing happens in either table. If someone else enters the same pop and neighborhood then it enters the data in table1 and increases the votes in table2 by 1. I have heard some people talking about "on duplicate key ignore" which I think would work if implemented as below but I am not actually sure that the command is real:
mysql_query("INSERT INTO `table1` VALUES ('$pop','$first', '$last', '$email',
'$neighborhood') on duplicate key ignore (INSERT INTO `table2`
VALUES ('$pop', '$neighborhood','$votes', '$city') ON DUPLICATE KEY UPDATE
`votes` = `votes` +1)");
I have the following code working but understand that it will enter data into table2
regardless of unique data in table1.
mysql_query("INSERT INTO `table1` VALUtS ('$pop','$first', '$last', '$email', '$neighborhood')");
mysql_query("INSERT INTO `table2` VALUES ('$pop', '$neighborhood', '$votes', '$city') ON DUPLICATE KEY UPDATE `votes` = `votes` +1");
Please let me know if you have any questions.

Why not have a single table? Change your unique key to pop,neighborhood,email (so pop,neighborhood are the leftmost two and can be used in a group by) and drop the 'votes' column. You can then run a query like SELECT pop, neighborhood, count(*) AS votes FROM table1 GROUP BY pop,neighborhood;
I don't think there's any such thing as ON DUPLICATE KEY IGNORE, but there is INSERT IGNORE INTO ... which basically says don't return any errors if the insert failed. If you need to keep separate tables you'll have to run the first query, check to see if you got a duplicate key error, then insert...on duplicate key update into the second table.

Related

insert into 2column table, avoiding duplicate records

I have a table with 2 columns, userid and messageid. I am updating it automatically through a php script, but I can't get a working insert statement. I don't mind if there are duplicates of userid, or duplicates of messageid (in fact there should be duplicates of both), I just don't want any duplicate of the same combination of userid and messageid. Is there any way to write a query that will do this for me, or do I have to handle it at the php level?
I've probably tried 20 different queries that I found on here and google, but have not gotten it right. This was the last thing I tried:
INSERT INTO interests_join (userid, interestid)
VALUES (1, 4)
WHERE NOT EXISTS
(SELECT userid, interestid FROM interests_join WHERE userid = 1 AND interestid = 4)
You can add a UNIQUE KEY, sql will refuse to insert a new row that is a duplicate of an existing one.
ALTER TABLE `interests_join` ADD UNIQUE `row` (`userid`, `interestid`);
Then you'll have to check from PHP if the query was successful or not (error #1062). You can't apply the key if there are duplicate rows, you have to remove them first .

Mysql, Insert new record into table B if foreign key exists in table A

There are a few similar questions on here. None provide a solution. I would like to INSERT a NEW record into table B, but only if a foreign key exists in table A. To be clear, I do not wish to insert the result of a select. I just need to know that the foreign key exists.
INSERT INTO tableB (tableA_ID,code,notes,created) VALUES ('24','1','test',NOW())
SELECT tableA_ID FROM tableA WHERE tableA_ID='24' AND owner_ID='9'
Clearly, the above does not work. But is this even possible? I want to insert the NEW data into tableB, only if the record for the row in tableA exists and belongs to owner_ID.
The queries I have seen so far relate to INSERTING the results from the SELECT query - I do not wish to do that.
Try this:
INSERT INTO tableB (tableA_ID,code,notes,created)
SELECT id, code, notes, created
FROM ( SELECT '24' as id, '1' as code, 'test' as notes, NOW() as created) t
WHERE EXISTS
(
SELECT tableA_ID
FROM tableA
WHERE tableA_ID='24' AND owner_ID='9'
)
I know it's a pretty much old answered question but it's highly ranked now in google search results and I think some addition may help someone in the future.
In some DB configuration, you may want to insert a row in a table that have two or more foreign keys. Let's say we have four tables in a chat application :
Users, Threads, Thread_Users and Messages
If we want a User to join a Thread we'll want to insert a row in Thread_Users in wich have two foreign keys : user_id, thread_id.
Then, we can use a query like this, to insert if both foreign keys exists, and silently fail otherwise :
INSERT INTO `thread_users` (thread_id,user_id,status,creation_date)
SELECT 2,3,'pending',1601465161690 FROM (SELECT 1 as nb_threads, 1 as nb_users) as tmp
WHERE tmp.nb_threads = (SELECT count(*) FROM `threads` WHERE threads.id = 2)
AND tmp.nb_users = (SELECT count(*) FROM `users` WHERE users.id = 3)
It's a little verbose but it does the job pretty well.
Application-side, we just have to raise an error if affectedRows = 0 and maybe trying to see which of the keys doesn'nt exists. IMHO, it's a better way to do the job than to execute two SELECT queries and THEN execute the INSERT especially when an inexistent foreign key probability is very low.

MySql Trigger INSERT... ON DUPLICATE KEY UPDATE not recognising columns

I have two tables in a Mysql database: "stock_pricing" and "DATA_IMPORT"
columns in first table: STOCK_ID, DATE, LAST_CLOSE_DOM_CURR
columns in second table: STOCK_ID, DATE, ADJ_CLOSE
The first table has an index on stock_id and date together. These have been defined as UNIQUE.
The second table has no index at all.
The second table has incoming data. On this table there is a BEFORE INSERT trigger that inserts incoming data into the first table.
If upon the insert trigger the combination of STOCK_ID and DATE violates the UNIQUE index of the first table, the ON DUPLICATE KEY UPDATE part of the trigger is fired.
I have tried every combination I can think of, but the trigger does not recognise my column names, any thoughts? Many thanks.
BEGIN
INSERT INTO stock_pricing (`STOCK_ID`, `DATE`, `LAST_CLOSE_DOM_CURR`)
VALUES (DATA_IMPORT.STOCK_ID, DATA_IMPORT.DATE, DATA_IMPORT.ADJ_CLOSE)
ON DUPLICATE KEY UPDATE
stock_pricing.STOCK_ID= DATA_IMPORT.STOCK_ID, stock_pricing.DATE= DATA_IMPORT.DATE, stock_pricing.LAST_CLOSE_DOM_CURR= DATA_IMPORT.ADJ_CLOSE;
END
You are referencing a table called data_import with no from clause. This is fixed using insert . . . select:
INSERT INTO stock_pricing (`STOCK_ID`, `DATE`, `LAST_CLOSE_DOM_CURR`)
SELECT DATA_IMPORT.STOCK_ID, DATA_IMPORT.DATE, DATA_IMPORT.ADJ_CLOSE
FROM DATA_IMPORT
ON DUPLICATE KEY UPDATE
stock_pricing.STOCK_ID= DATA_IMPORT.STOCK_ID, stock_pricing.DATE= DATA_IMPORT.DATE, stock_pricing.LAST_CLOSE_DOM_CURR= DATA_IMPORT.ADJ_CLOSE;
A more typical way of writing such a query is:
INSERT INTO stock_pricing (`STOCK_ID`, `DATE`, `LAST_CLOSE_DOM_CURR`)
SELECT di.STOCK_ID, di.DATE, di.ADJ_CLOSE
FROM DATA_IMPORT di
ON DUPLICATE KEY UPDATE STOCK_ID = VALUES(STOCK_ID),
DATE = VALUES(DATE),
LAST_CLOSE_DOM_CURR = VALUES(LAST_CLOSE_DOM_CURR);
For ON DUPLICATE KEY UPDATE to work, you need a unique index or primary key. I assume you have these.
Finally, this code looks a bit strange for a trigger, because there are no references to NEW or OLD. If you are still having trouble with the trigger, then ask another question and include the full code for the trigger.

INSERT INTO...SELECT - Primary key conflict - error #1062

I have a database: groupofficecom has two tables:
cal_events: id(Primary key), name, start_time, description,....
cf_cal_events: model_id (Primary key), col_1, col_2, col_3,....
I'm trying to execute the following code:
INSERT INTO groupofficecom.cf_cal_events (model_id,col_1,col_2,....)
SELECT groupofficecom.cal_events.ID, '0' AS col_1, '' AS col_2,....
FROM groupofficecom.cal_events
But it keeps giving me error #1062 - Duplicate entry '155' ('155' is the 'id' from cal_events) for key 'PRIMARY'
I want the primary key model_id to be the same value as id in cal_events because the table cf_cal_events is just complementary fields for cal_events (this is a program, so I can't change its database, it'll be gone on the first update)
Thank you guys!
This means there already is an entry with that id in the target table.
First, check how this can be.
Then, use one of the solutions described here as is appropriate:
"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"
i.e. UPDATE or IGNORE.
You should use an ORDER BY with the select you have and the solution above to choose which entries get ignored (all but the first entry with IGNORE).
It is also possible that you want something different entirely, i.e. to use an UPDATE statement instead of an INSERT statement.
In fact I found a very good function, it's very similar to the INSERT but smarter:
REPLACE INTO database (column_1, column_2)
SELECT source_column1, 'value' AS column2
FROM table;
Or:
REPLACE INTO database (column_1, column_2)
VALUES ('value1', 'value2')
FROM table;
Works like magic!
It inserts new items to the destination table, and if it finds a row with the same primary key value, it erases it and re-inserts the new value (it works great for updating a table from another one)
I hope this solves your problem like it solved mine ;)

MySQL: INSERT IGNORE or ON DUPLICATE KEY UPDATE with checking multiple and not unique columns

i want to insert rows IF a row containing the specific values exists, and if not update it.
Concretely:
A column user_id=5, user_zip=12345, distance=600 exists on the database.
If i try to insert user_id=5, user_zip=12345, distance=700 it should just update the distance
but i try to insert user_id=5, user_zip=67890, distance=800 it should insert a new row.
I can't define the columns user_zip and distance unique, so that i can use the on duplicate key update.
I think you are misunderstanding how ON DUPLICATE KEY UPDATE works. With a unique constraint on (user_id, user_zip), this should work:
INSERT INTO yourTable (user_id, user_zip, distance) VALUES (5,12345,600)
ON DUPLICATE KEY UPDATE distance=600;
You don't have to define user_zip unique (that's how I understand your question), just the combination of user_id and user_zip. So you still can have 2 or more rows with the same user_id, just the user_zip can't match on those rows.