MySQL AFTER Update trigger with New.col<> OLD.col - mysql

The goal here is to update and concatenate a text field from one table to another based on conditions. When a text col gets updated with some text from a user form, run After update trigger.
The trigger runs but updates all the columns not just the one that has changed.Trying to understand how to just update the correct row only.
Here's what i have so far-
SQLFiddle
| ID | SUBID | SWNOTES |
|----|-------|---------| Table 1
| 1 | 40 | test |
| 2 | 60 | |
| ID | SUBID | CONTENT | SWFLAG |
|----|-------|---------|--------|
| 1 | 40 | hello | 0 | Table 2
| 2 | 60 | nothing | 0 |
CREATE TRIGGER `updatecontentnotes` AFTER UPDATE ON `tab1`
FOR EACH ROW
BEGIN
IF New.swnotes <> OLD.swnotes
THEN
Update `tab2`
Inner Join `tab1` ON `tab2`.`subid` = `tab1`.`subid`
Set `tab2`.`swflag` = '1',`tab2`.`content` = CONCAT(`tab2`.`content`, `tab1`.`swnotes`)
Where `tab2`.`subid` = `tab1`.`subid` AND `tab2`.`swflag` = '0';
END IF;
END//
And if I update the table with say:
Update `tab1`
set `swnotes` = "new"
where `subid` = '60'
I get :
| ID | SUBID | CONTENT | SWFLAG |
|----|-------|------------|--------|
| 1 | 40 | hellotest | 1 |
| 2 | 60 | nothingnew | 1 |
Now I know it is doing what I am telling it to do. I want to update just the row that is updated. Thanks for any help on this.

Since the contents of your trigger will run for every row on tab1, you need to be more restrictive in your WHERE clause so that it will only affect the rows that have been updated. Right now it updates every row on tab2
Try adding this to your trigger SQL:
From:
Where `tab2`.`subid` = `tab1`.`subid` AND `tab2`.`swflag` = '0';
To:
Where `tab2`.`subid` = `tab1`.`subid` AND `tab2`.`swflag` = '0' AND `tab2`.`id` = OLD.id;
This produces the results that I think you are looking for:
| ID | SUBID | CONTENT | SWFLAG |
|----|-------|------------|--------|
| 1 | 40 | hello | 0 |
| 2 | 60 | nothingnew | 1 |
The updated SQLFiddle is here:
http://sqlfiddle.com/#!2/9fa2d2/1/0

Related

how to convert table columns into a table in mysql?

I know it's a bad title, but I don't know how to describe my question in a line.
I want to store following information in my database.
+----+----------+-----------+-----------+
| id | name | cluster_1 | cluster_2 |
+----+----------+-----------+-----------+
| 1 | content_1| true| false |
| 2 | content_2| false| true |
| 3 | content_3| true| true |
+----+----------+-----------+-----------+
cluster_1=true means that the content exists on the cluster_1.
As some clusters may added or deleted, I want to store my cluster information in a new table "clusters", and indicate the relation between contents and clusters with a "content_cluster" table.
table contents
+----+----------+
| id | name |
+----+----------+
| 1 | content_1|
| 2 | content_2|
| 3 | content_3|
+----+----------+
table clusters
+----+----------+
| id | name |
+----+----------+
| 1 | cluster_1|
| 2 | cluster_2|
+----+----------+
table content_cluster
+----------+----------+
|content_id|cluster_id|
+----------+----------+
| 1 | 1 |
| 2 | 2 |
| 3 | 1 |
| 3 | 2 |
+----------+----------+
But, writing in this way, I don't know how to get a content which is on cluster_1 but isn't on cluster_2, or vice versa. I have to do this query frequently. So what is the efficient way to do this?
how to get a content which is on cluster_1 but isn't on cluster_2
in general
SELECT contents.name
FROM contents
JOIN content_cluster ON contents.id = content_cluster.content_id
LEFT JOIN clusters ON clusters.id = content_cluster.cluster_id
GROUP BY contents.name
HAVING SUM(clusters.name = 'cluster_1') -- not zero, may add ">0"
AND !SUM(clusters.name = 'cluster_2') -- zero, may replace NOT ("!") with "=0"
The following should work:
-- For cluster 1
INSERT INTO new_table (content_id, cluster_id)
SELECT old_table.content_id, 1
FROM old_table
WHERE old_table.cluster_1 = TRUE;
-- For cluster 2
INSERT INTO new_table (content_id, cluster_id)
SELECT old_table.content_id, 2
FROM old_table
WHERE old_table.cluster_2 = TRUE;

How to insert data for one column for all the rows in single query in Mysql?

+----+------------+------------+------------+----------+
| id | phone_no | join_date | city | blood_gp |
+----+------------+------------+------------+----------+
| 1 | 80077672xx | 1997-07-19 | Delhi | NULL |
| 2 | 80077642xx | 1998-07-19 | New Delhi | NULL |
| 3 | 80477642xx | 1999-07-19 | Mumbai | NULL |
| 4 | 80077654xx | 1997-05-31 | Kolkata | NULL |
+----+------------+------------+------------+----------+
I want to enter all the blood groups at once . Is there a way to do so ?
you can use single query with select and update
UPDATE table1 , (SELECT * FROM table2 where 1) src
SET table1.blood_gp = src.filed2 where 1 ;
if you want to insert multiple row data using single query then use this code
INSERT INTO yourtable (x,y,z) VALUES (a1,a2,a3), (b1,b2,b3);
or if you want to update one column value all filed then use this code
update yourtable set blood_gp = 'yourvalue' where 1;
if any problem then inform me
Just make an update query without where clause.
update table set blood_gp = 'value'
That's generalize query.

Mysql trigger with joins

I have three MYSQL tables that all relate to each other as you can see below.
I'm currently storing the dateofjob twice because i do not know how to create table joins in a trigger. Currently i'm using this trigger on the specimen details table
CREATE TRIGGER `NewAge_update` BEFORE UPDATE ON `Speciemn_Details`
FOR EACH ROW BEGIN
SET NEW.Due_Date = DATE_ADD(NEW.CastDate,INTERVAL NEW.Age DAY);
END
And this is working perfectly, but i want to be able to remove the column dateofjob from the specimen details table and calculate the duedate from the Job_Details table to save myself from having double data.
I will have to join the job_details.ID with the Test_Details.PARENTID and the Test_Details.TESTID with the specimen_details.TESTID, I just don't know how to do this inside a trigger. any help would be appreciated greatly
I've attempted to be as detailed as possible BUT If anymore information is required please ask me
Job_Details
+----+-----------+
| ID | dateofjob |
+----+-----------+
| 1 | 1/01/2015 |
| 2 | 1/01/2016 |
| 3 | 1/01/2017 |
+----+-----------+
Test_Details
+----------+--------+--------------+
| ParentID | TestID | TestLocation |
+----------+--------+--------------+
| 2 | 2154 | Barn |
| 2 | 2155 | Barn |
| 1 | 8055 | Yard |
+----------+--------+--------------+
Specimen_Details
+--------+----------+---------+-----------+-----------+
| TestID | Specimen | TestAge | dateofjob | Duedate |
+--------+----------+---------+-----------+-----------+
| 2154 | A | 3 | 1/01/2016 | 4/01/2016 |
| 2154 | B | 8 | 1/01/2016 | 9/01/2016 |
| 8055 | A | 2 | 1/01/2015 | 3/01/2015 |
+--------+----------+---------+-----------+-----------+
Joins inside trigger code really aren't any different from joins in any other procedural code, except that you can't query the triggering table and you instead have the OLD and NEW pseudorecords. If I've understood your description, you want to do something like
CREATE TRIGGER `NewAge_update` BEFORE UPDATE ON `Specimen_Details`
FOR EACH ROW
BEGIN
DECLARE jobdate DATE;
SELECT dateofjob
INTO jobdate
FROM job_details j, test_details t
WHERE j.ID = t.ParentID
AND t.TestID = NEW.TestID;
SET NEW.Duedate = DATE_ADD(jobdate, INTERVAL NEW.TestAge DAY);
END;
(Don't forget that trigger bodies are procedural, so you don't have to do everything in a single statement.)

Populate values from one table

I am trying to populate an empty table(t) from another table(t2) based on a flag field being set. He is my attempt below and the table data.
UPDATE 2014PriceSheetIssues AS t
JOIN TransSalesAvebyType2013Combined AS t2
SET t.`Tran_Type`=t2.`Tran_Type` WHERE t.`rflag`='1';
When I run the script, I receive (0) zero records affected.??
+-----------+----------------+-------------------+-------+-------+
| Tran_Type | RetailAvePrice | WholesaleAvePrice | Rflag | Wflag |
+-----------+----------------+-------------------+-------+-------+
| 125C | 992 | 650 | 1 | NULL |
| 2004R | 1500 | NULL | 1 | NULL |
| 4EAT | 1480 | 1999 | 1 | 1 |
+-----------+----------------+-------------------+-------+-------+
I think you should just do the following
INSERT INTO 2014PriceSheetIssues
( `fldX`, `fldY` )
VALUES (
SELECT `fldX`, `fldY`
FROM TransSalesAvebyType2013Combined
WHERE 2014PriceSheetIssues.`rflag`='1'
)
The select query gets the values and the insert puts it in the (empty) other table.

mySQL cross table field linking

Basically I have two tables A and B. These are linked by unique ID's where the entries in B point to one entry in A. The entries in A and B also have a 'status' field denoting if the entry is active or not...
My questions is therefore; is it possible to link the status field of the entries in B and have them update, every time the 'status' field in A (pointed to by the unique ID) is updated? I could do this fairly easy with an SQL command however I'm wondering if there is a more automatic solution. Example:
table A
|------ID------|----status----|
| 1 | on |
| 2 | on |
|---------------|----------------|
table B
|-----eID------|------ID------|----status----|
| 1 | 1 | on |
| 2 | 1 | on |
| 3 | 2 | on |
|---------------|---------------|----------------|
I then run:
UPDATE `A` SET `status` = 'off' WHERE `ID` = 1;
And the result would be:
table A
|------ID------|----status----|
| 1 | off |
| 2 | on |
|---------------|---------------|
table B
|-----eID------|------ID------|----status----|
| 1 | 1 | off |
| 2 | 1 | off |
| 3 | 2 | on |
|---------------|---------------|----------------|
Is that possible?
Many Regards,
Andreas
i hope this trigger code can help u.
CREATE TRIGGER `abc` AFTER UPDATE ON `tablea` FOR EACH ROW BEGIN UPDATE tableb SET STATUS = new.status WHERE id = new.id;
END