MySQL - Update field in insert into query from select query - mysql

I have following two tables A and B.
I would like to insert records from table A into table B but with new orderNum value as and when new records are being added into table B.
I have following query but not working as expected.
INSERT INTO B (refId, userId, orderNum)
SELECT id, '1', (SELECT count(refId) + 1 FROM B WHERE userId = 1) as orderNum
FROM A
WHERE is_mendatory IS NOT NULL
ORDER BY is_mendatory ASC
Let say I have 3 records exist in table B and using SELECT query I am going to insert 5 more records. So those new 5 records should be inserted with orderNum from 4,5,6,7,8.
But currently it only sets 4 as orderNum for new 5 records.
Can anybody suggest something on this?
Edit:
I am getting on 4 in orderNum field for new 5 records.

Create a before insert trigger,count the rows in B for each INSERT,store the number in a variable,update the table with the number of rows.
DELIMITER //
CREATE TRIGGER orderNum_after_insert
BEFORE INSERT
ON B FOR EACH ROW
BEGIN
SET #orderNo:=(SELECT COUNT(*) FROM B);
SET NEW.orderNum=#orderNo;
END; //
DELIMITER ;

Related

Fill Column of SQL Table

I'm trying to fill a certain column of a SQL table with data from another table. I have a column named "size" in my table which should return the number of rows in the 2nd table where the id of both rows is the same. Is there a way to populate a SQL column based on a certain command? I would love to be able to fill the column based on this command:
SELECT count(*)
FROM second_table
WHERE id = "row_id";
Here is a sample database with the two tables:
Table 1
Name
id
tiger
1
lion
2
gazelle
1
Here is the desired output for Table 2:
id
Number of Animals
1
2
2
1
I am trying to fill the Number of Animals column but do it automatically and dynamically when another row is added or deleted to Table 1, which is why I want the Select count(*) SQL statement as the code for the column.
One method is a correlated subquery:
update table1 t1
set size = (select count(*)
from table2 t2
where t2.id = t1.id
);
If you need to do this dynamically (as data is inserted), then you would need to use a trigger. However, I would suggest that you calculate the value as needed, unless there is a specific reason why you need to store it.
I guess you need something like this:
CREATE TRIGGER UpdateAnimalCountTable2
AFTER INSERT ON `Table1` FOR EACH ROW
begin
DECLARE NewCount int;
SELECT count(1)
INTO #NewCount
FROM Table1
WHERE Table1.id= NEW.id;
UPDATE Table2
SET NoOfAnimals = #NewCount
WHERE id = NEW.id;
END;
Above is the trigger which will be executed after every insert in Table1 and will update the count in Table 2 for ID which just got inserted in Table1.

update row if already exist or else insert new record in table using mysql

SELECT * FROM user_referral;
id user_id new_user_id bonus_type amount
1 123 own 25
2 234 own 25
3 123 456 referral 25
SELECT * FROM user_points;
id user_id referral_points
1 123 50
2 234 25
I am working for an application and I have two tables like above. If user join my application than he will get some bonus.
when user join he get 25 rupees and when he refer another friend again he get 25 more.So first record will come to user_referral table where individual amount will be stored and for particular user total amount will be stored in user_points table.
Now I am writing trigger in user_referral table to update amount in user_points table using mysql, I want to check if user already exist in user_points table that amount should be updated else it should insert new record.
I tried if else condition but its not working, I don't know how to check duplicate records..
if (SELECT user_id FROM user_points WHERE user_id IN (SELECT new.user_id FROM user_referral)) then
update user_points set
referral_points=referral_points+new.point,
updated_time=new.inserted_time;
else
INSERT INTO user_points (user_id,referral_points,updated_time)
VALUES (new.user_id, new.point, new.inserted_time);
end if;
Also I tried using on duplicate key update, but in my case it is inserting new row instead it should update previous one.
Any help will be appreciated..
Consider the insert ... on duplicate key syntax:
insert into user_points(user_id, referral_points)
values(:user_id, :referral_points)
on duplicate key update referral_points = referral_points + values(referral_points)
For this to work, you need a unique constraint on user_points(user_id).
When an insert occurs on a user_id that already exists, MySQL goes to the on duplicate key clause, where the new referral_points value is added to the existing value.

MySQL Trigger After Insert, Action JOIN 2 tables

I need to create a trigger (after insert on one table) on MySQL, but the action needs to join 2 tables, for inserting into a third table. My script below returns no error, but the row is not inserted into the third table.
The first table (on which the after-insert trigger should work):
Z_TAXO
ID term_ID taxo_name
1 1 dept
2 2 staff
3 4 course
4 5 dept
The second table to be joined in the trigger:
Z_TERM
term_ID name
1 Engineering
2 Andy
4 Metallurgy
5 Business
6 Arts
The third table. If the Z_TAXO table has a new row with taxo_name = "dept", the row (joined with table Z_TERM) needs to be inserted into this table:
Z_DEPTS
ID dept_name
1 Engineering
4 Business
I created a trigger:
delimiter //
CREATE TRIGGER TRG_NEW_DEPT
AFTER INSERT ON Z_TAXO
FOR EACH ROW
BEGIN
DECLARE _dept_ID bigint(20);
DECLARE _dept_name varchar(200);
IF Z_TAXO.taxo_name = "DEPT" THEN
BEGIN
SELECT Z_TAXO.ID INTO _dept_ID FROM Z_TAXO, Z_TERM
WHERE Z_TAXO.ID = new.Z_TAXO.ID AND Z_TAXO.term_ID = Z_TERM.term_ID;
SELECT Z_TERM.name INTO _dept_name FROM Z_TERM, Z_TAXO
WHERE Z_TAXO.term_ID = Z_TERM.term_ID AND Z_TAXO.ID = new.Z_TAXO.ID;
INSERT INTO Z_DEPTS (ID, dept_name) VALUES (_dept_ID, _dept_name);
END;
END IF;
END//
delimiter ;
Then inserted a row to the Z_TAXO table:
INSERT INTO Z_TAXO (ID, term_ID, taxo_name) VALUES (5, 6, "dept");
Expecting to have this new row in table Z_DEPTS:
ID dept_name
5 Arts
But when I select * from Z_DEPTS, the result is still:
ID dept_name
1 Engineering
4 Business
What can be wrong? I can't modify the design of the tables, because they came from a wordpress Plugin. Thanks in advance!
Couple of comments about your code. 1) When using new. qualifiers you don't further qualify with the table name so new.z_taxo.id is invalid andd should simply be new.id 2) You don't need a begin..end block in a mysql if statement 3) if just doesn't make sense referring to the table z_taxo in your select stataments - a simple insert select will do.
try
drop trigger if exists trg_new_dept;
delimiter //
CREATE TRIGGER TRG_NEW_DEPT
AFTER INSERT ON Z_TAXO
FOR EACH ROW
BEGIN
INSERT INTO Z_DEPTS (ID, dept_name)
select term_id, name
from z_term
where term_id = new.term_id;
END//
delimiter ;

Limiting table rows

How can I store only 10 rows in a MySQL table? The older rows should be deleted when a new row is added but only once the table has 10 rows.
Please help me
You could achieve this with an after insert trigger, delete the row where it is min date. e.g. DELETE FROM myTable WHERE myTimestamp = (SELECT MIN(myTimestamp) FROM myTable) but that could in theory delete multiple rows, depending on the granularity of your updates.
You could have an incrementing sequence, and always just delete the min of that sequence.
The question is why you'd want to do this though? It's a slightly unusual requirement.
A basic example (not validated/executed, I don't have mySQL on this particular machine) would look something like.
CREATE TRIGGER CycleOldPasswords AFTER INSERT ON UserPasswords FOR EACH ROW
set #mycount = SELECT COUNT(*) FROM UserPasswords up where up.UserId = NEW.UserId;
if myCount >= 10 THEN
DELETE FROM UserPasswords up where up.Timestamp = (SELECT min(upa Timestamp) FROM UserPasswords upa WHERE NEW.UserId = upa.UserId) AND NEW.UserId = up.UserId;
END
END;
You can retrieve the last inserted id when your first row is inserted, and store it in a variable. When 10 rows are inserted, delete the row having id < id of the first inserted record. Please try it.
first of all insert all values using your insert query
and then run this query
delete from table_name where (cond) order by id desc limit 10
must specify an id or time in one column

Delete columns on couple of conditions

In a previous question I asked how I could sum up a total based on some conditions: Count total on couple of conditions
Suppose I have a table like this:
id col1 col2 col3
1 a 1 k1
2 a 2 k2
3 a -3 k3
4 b 3 k4
Now, when I get id=1, I want to delete all the rows where col1=a.
When I get id=4, I want to delete all the rows where col1=b.
How would I do this in SQL?
I tried based upon previous answer:
DELETE FROM table WHERE (col1) IN (SELECT col1 FROM table WHERE id = '1')
But that gave me an error: #1093 - You can't specify target table 'table' for update in FROM clause
This has been many times on stackowerflow, you cannot UPDATE/DELETE table with data from nested select on the same table. There're two ways to do this:
Load all data before (for example via php, sql procedure)
Create temporary table like the one you're using, clone data and use temporary table to select items
i have another suggested solution for this. What if you create a STORED PROCEDURE for this problem?
like this:
DELIMITER $$
CREATE PROCEDURE `DeleteRec`(IN xxx varchar(5))
BEGIN
DECLARE oID varchar(5);
SET oID := (SELECT col1 FROM table WHERE id = '1');
DELETE FROM table WHERE col1 = oID;
END$$
DELIMITER ;
do this helps you?