Inserting a foreign key, on missing key, update - mysql

I have two tables:
tbl1:
============================
ID | TOKEN(indexed)
============================
1 | 2176
2 | 2872
3 | 2881
4 | 1182
tbl2:
=======================
ID | TOKEN_REF
=======================
1 | 2
2 | 3
3 | 1
4 | 1
in each iteration the server would receive a 'token', and would update tbl1 if no token exists, in this example token "5241" would require an insert into tbl1.
I need to update tbl2 where tbl2.ID is AUTO_INCREMENTed whenever a token is received (existing or not).
If the token is a new one, first update tbl1, and only then update tbl2 with the id of the new token.
I was thinking on the INSERT ON EXIST UPDATE, but I don't know how to combine it into a single command.
To summarize:
I need to INSERT ON EXIST UPDATE tbl1 in each iteration and INSERT the resulting ID into tbl2 in a single command. is that possible?
ideas?

I have prepared an SQLFiddle of as per Ondřej's suggestion, which may be found here.
In the schema I have proposed the following After Insert trigger:
CREATE TRIGGER tbl1_ai AFTER INSERT ON tbl1
FOR EACH ROW
INSERT INTO tbl2(TOKEN_REF)
VALUES(new.ID);

Related

Insert if pair doesn't exist

If I have table with 4 columns: rowId | userOneId | userTwoId | timestamp
Is it possible to check whether a pair of users exist and update timestamp if it does? And if it doesn't exist insert new row?
Example of table with expected results:
rowId | userOneId | userTwoId | timestamp
1 a b <timestamp>
2 a c <timestamp>
Now if I want to insert into userOneId a and to userTwoId b, it will update the timestamp. Also possible is if userOneId is b and userTwoId is b update row 1 timestamp as well (would love to see both options - i.e for exact pairs, and for reverse pairs)
THIS ANSWERS THE ORIGINAL VERSION OF THE QUESTION.
I think you want insert . . . on duplicate key update:
insert into t(useroneid, usertwoid, timestamp)
values ($userondid, $usertwoid, $timestamp)
on duplicate key update timestamp = values(timestamp);
In order for this to work, you need a unique index on (useroneid, usertwoid):
create unique index unq_t_useroneid_usertwoid on t(useroneid, usertwoid);

Populate a table with random set of rows from another table on insert using a trigger

I got this problem.
I have a mysql database with this tables:
USERS(Cod,Interests)
SURVEY(Cod,Target_Interests)
USERS_OF_A_SURVEY(CodSurvey,CodUser)
with Interests having the same set of values of Target_Interests.
I would like having a trigger in my database that, after an insert on SURVEY,puts 1000 entries on USERS_OF_A_SURVEY in this way:
for example: i put into SURVEY the value SURV001,MUSIC.
Now the trigger should put 1000 entries on USERS_OF_A_SURVEY with CodSurvey fixed at SURV001, and CodUser randomly from the users with Interests = MUSIC.
Don't know if I explained my problem properly, I hope yes. HELP ME!
Thanks
Are you looking for this?
CREATE TRIGGER tg_survey_after_insert
AFTER INSERT ON survey
FOR EACH ROW
INSERT INTO users_of_a_survey (codsurvey, coduser)
SELECT NEW.cod, cod
FROM users
WHERE interests = NEW.target_interests
ORDER BY RAND()
LIMIT 1000
;
Insert a few rows
INSERT INTO survey VALUES('SURV001', 'music');
INSERT INTO survey VALUES('SURV002', 'music');
Content of users_of_a_survey after insert
| CODSURVEY | CODUSER |
-----------------------
| SURV001 | 3 |
| SURV001 | 1 |
.....................
| SURV002 | 1 |
| SURV002 | 4 |
......................
Here is SQLFiddle demo.
UPDATE:
And if i would like to do the inverse? Delete all users from
"users_of_a_survey" when I delete their survey?
You can either go with a BEFORE DELETE trigger or with FOREIGN KEY ... ON DELETE CASCADE
A trigger may look like
CREATE TRIGGER tg_survey_after_delete
BEFORE DELETE ON survey
FOR EACH ROW
DELETE FROM users_of_a_survey
WHERE codsurvey = OLD.cod
;
Here is SQLFiddle demo.

Merge 2 databases into another one without duplicate records

I have a question I want to merge 2 databases into another one but the problem is there are duplicate rows. So how can I merge the 2 databases into another one without duplicate records? I hope someone can help me.
Database 1
Name | Number | Code
Demo | 0293 | 827
Test | 0482 | 923
Database 2
Name | Number | Code
Lol | 0223 | 182
Stack| 1923 | 829
Demo | 0293 | 827
Thanks
This should really be done with a unique key and ON DUPLICATE KEY. If not willing to do that, the following would also work:
Assuming the tables are identical and that you only want to exclude a row when ALL columns are the same as a row in the target table.
INSERT into Table1
SELECT * from Table2
WHERE concat(Name,'|',Number,'|',Code) not in (
SELECT concat(Name,'|',Number,'|',Code)
FROM Table1
)
Select A.*,B.* from TABLE1 AS A,TABLE2 AS B where A.code=B.code GROUP BY A.code;
I think you are talking about TABLE not DATABASE. Use GROUP BY clause or find DISTINCT value with the query. And you have not specified any primary key..so read mysql tutorial first..

Update many-to-many relation table without violating primay contraint

Considering two tables with a many-to-many relation :
Company Speciality
--------- ---------
id id
--------- ---------
1 21
2 22
3 23
4
CompanySpeciality
--------------------------
company_id | speciality_id
--------------------------
1 | 21
1 | 22
4 | 21
4 | 23
I want to delete company 4, and associate its specialities to the company 1.
If I use a simple UPDATE statement on CompanySpeciality to set "company_id = 1 WHERE company_id=4", I'm facing the primary contraint violation because the pair 1|21 already exists.
Is the a way to update the relation table with a single query ? This query should only affect rows that will not be duplicated.
The result would be :
CompanySpeciality
--------------------------
company_id | speciality_id
--------------------------
1 | 21
1 | 22
1 | 23
something to the effect of:
UPDATE CompanySpecialty
SET company_id=1
WHERE company_id=4
AND NOT EXISTS (SELECT * FROM CompanySpecialty cs WHERE cs.company_id=1 AND cs.specialty_id=CompanySpecialty.specialty_id);
should work for you. (i haven't tested the exact syntax, but using a NOT EXISTS clause should help you eliminate the problem of violating primary key restraints).
you will then have to remove the extra records left in the table for company 4 in a separate query:
DELETE FROM CompanySpecialty
WHERE company_id=4;
You don't want to UPDATE, you want to INSERT and ignore dupes:
INSERT IGNORE INTO CompanySpeciality (company_id, speciality_id)
SELECT 1, speciality_id
FROM CompanySpeciality
WHERE company_id=4
you won't be able to both update and delete records in a single query. You can use transactions:
mysql: select, insert, delete and update in one query

Mysql (php) update or replace shopping bag content in one query, with multiple values

I've got the flowing tables in mysql db for a shopping bag:
BAGS
-----
| bagID | date_added |
| primary Key | |
------------------------------
| 1 | 2012-01-04 |
BAGS_CONTENT
-----
| ID | productID | qyt |
| foreign key->bagID | | |
-----------------------------------------
| 1 | 103 | 4 |
// $sql Could contain this:
$sql = "(1,103,5),
(1,101,3)";
INSERT INTO BAGS_CONTENT
( ID, product_id, qty)
VALUES
".$sql."
I like the BAGS_CONTENT to update an existing record (if exists ID and product_id) and add a new row if not exists (the ID and product_id).
I've tried using REPLACE INTO and ON DUPLICATE KEY UPDATE but I can't get it to work.
May be its has something to do with the keys?
How should you query the db in a situation like this?
ON DUPLICATE KEY UPDATE triggers the UPDATE statement when the unique value is already existing in the table. Make sure that you've set the right fields to be unique. I think you have to put an UNIQUE on ID and productID (both in one combined unique):
ALTER TABLE BAGS_CONTENT ADD UNIQUE (ID, product_id)
Your query should look like this:
INSERT INTO BAGS_CONTENT (ID, product_id, qty) ".$sql." ON DUPLICATE KEY UPDATE qty = VALUES(qty);
Here's more information about 'on duplicate key':
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
To use ON DUPLICATE KEY UPDATE you first need to create a unique key on BAGS_CONTENT(ID,productID)
Then use
INSERT INTO BAGS_CONTENT (ID,productID,qyt) VALUES(1,101,3) ON DUPLICATE KEY UPDATE qyt=VALUES(qyt);
You need to create a key error in order to trigger the special behavior of REPLACE. To get the proposed behavior add an index:
mysql> create table bag_content (id INT,productID INT,qty SMALLINT);
mysql> create unique index baggy on bag_content (id,productID);
mysql> replace bag_content values(1,111,5);
mysql> replace bag_content values(1,112,5);
mysql> replace bag_content values(1,111,500);
mysql> select * from bag_content;
+------+-----------+------+
| id | productID | qty |
+------+-----------+------+
| 1 | 111 | 500 |
| 1 | 112 | 5 |
+------+-----------+------+
Also watch out: you're using SQL supported in mysql only. The pejorative is 'their sql'... because of all the innovations of mysql that don't go through a standards process. The replace functionality is great, but it will increase the barrier to moving your code to other databases.