I want to update table cases_proceedings but it will check some criteria for this in the other table cases_attach_files i.e.
SELECT cp.sno FROM cases_proceedings cp, cases_attach_files cf
WHERE cp.`case_sno` = cf.`case_sno` AND cf.page_lbl_sno = 10 AND
cp.`is_decided` = 0
But when i want to update the first table value and search the sno of the first table by using the IN operation with subquery like this:
UPDATE cases_proceedings
SET `is_decided` = 1
WHERE sno IN(SELECT cp.sno FROM cases_proceedings cp, cases_attach_files cf
WHERE cp.`case_sno` = cf.`case_sno` AND cf.page_lbl_sno = 10 AND
cp.`is_decided` = 0);
It shows an error:
Error Code: 1093
You can't specify target table 'cases_proceedings' for update in FROM clause
i don't know how to fix this?
One workaround here is to wrap the subquery in another subquery:
UPDATE cases_proceedings
SET is_decided = 1
WHERE sno IN
(
SELECT sno
FROM
(
SELECT cp.sno
FROM cases_proceedings cp
INNER JOIN cases_attach_files cf
ON cp.case_sno = cf.case_sno AND
cf.page_lbl_sno = 10 AND
cp.is_decided = 0
) t
);
The extra subquery works around the error because it forced MySQL to materialize the subquery containing the joins.
According to documentation, In MySQL, you can't modify the same table which you use in the SELECT part.
You can either wrap it in subquery or joining both tables as shown below:
UPDATE cases_proceedings cp
INNER JOIN cases_attach_files cf
ON cp.case_sno = cf.case_sno
AND cf.page_lbl_sno = 10
AND cp.is_decided = 0
SET cp.is_decided = 1
Related
I fired this query where I join two tables and output some of the columns of both tables:
SELECT B.option_id, B.product_id, A.title, B.identifier
FROM `catalog_product_option_title` A JOIN
`catalog_product_option` B
ON A.option_id = B.option_id
WHERE A.title = "Breite"
Result:
Now I need to enter the example value xyz on the column identifier in the result, everywhere. I would go ahead and do this by hand.
How can I make use of the update statement from MySQL to solve this without having to manually change it by hand?
I tried it like this:
UPDATE `catalog_product_option`
SET identifier = 'xyz'
WHERE option_id IN (
SELECT A.option_id
FROM `catalog_product_option_title` A
JOIN
`catalog_product_option` B
ON A.option_id = B.option_id
WHERE A.title = "Breite"
)
But the simulation of this query returned that this would change 0 lines.
UPDATE
I called the sql without simulating it, and now I get this error:
1093 - Table 'catalog_product_option' is specified twice, both as a target for 'UPDATE' and as a separate source for data
You could rewrite your query as a JOIN:
UPDATE `catalog_product_option` B
JOIN `catalog_product_option_title` A ON A.option_id = B.option_id
SET B.identifier = 'xyz' WHERE A.title = "Breite"
Can you try like this please?
UPDATE `catalog_product_option`
SET identifier = 'xyz'
WHERE option_id IN (
SELECT option_id FROM (SELECT A.option_id
FROM `catalog_product_option_title` A
JOIN
`catalog_product_option` B
ON A.option_id = B.option_id
WHERE A.title = "Breite") as x
)
Im trying to change some records in my database but sadly my sql knowledge is a bit limited. After googling and reading stuff online I have managed to write a select statement in which i can find the records that I want to update but i dont understand the logic to write the update statement to do it. I have to make several similar update statements so I hope this one I can figure out the rest myself
This is the select statement I have:
SELECT
MG.id,
MG.status,
MG.fin,
MG.execDateTime,
EXISTS
(
SELECT 1
FROM Mtask T
JOIN MTaskHis TH ON TH.t_id= T.id
WHERE T.tg_id = MG.id
AND YEAR(TH.dateTime) = 2019
) AS hasExecStart,
NMG.id,
NMG.execDateTime,
EXISTS
(
SELECT 1
FROM Mtask T
JOIN MTaskHis TH ON TH.t_id = T.id
WHERE T.tg_id = NMG.id
AND YEAR(TH.dateTime) = 2019
) AS hasExecNext
FROM Management_Group MG
JOIN MT_Groupman MTGM ON
MG.tgm_id = MTGM.id
LEFT JOIN Management_Group NMG ON MTGM.id =
NMG.tgm_id AND YEAR(NMG.execDateTime) = 2019
JOIN Management_Man MM ON MTGM.man_id = MM.id
JOIN Location L ON MM.location_id = L.id
WHERE L.org_id = 69
AND MG.stat != 'DELETED'
AND YEAR(MG.execDateTime) = 2018
AND MM.Type= 9
AND MG.fin != 1
AND EXISTS
(
SELECT 1
FROM Mtask T
WHERE T.tg_id = MG.id
AND T.stat = 'execution'
)
HAVING hasExecNext = 0 AND hasExecStart = 1
I know standard updates in sql:
UPDATE <TABLENAME>
SET <fieldName> = <value>
WHERE <conditons>
Except I do not know how to convert this select statement I have made into an update statement, reason for that is:
- Where do I put the exist alias in the update statement
- I also dont understand when or where to put all the JOINS in the from statement
- What about the HAVING
What is the best way to do joined updates like this?
In an UPDATE you can join the table you want to update to a sub-query that contains your current query.
UPDATE YourTable t
JOIN
(
<< add your query here >>
) q ON q.SomeKeyField = t.SomeKeyField
SET t.FieldName = q.FieldNameFromSubquery,
t.OtherFieldName = q.OtherFieldNameFromSubquery
I am trying to performing update operation on value which meet certain criteria. My tables CAPD, CAMP, CAD. But I get error of
Error Code: 1093. You can't specify target table 'CAPD' for update in
FROM clause
UPDATE CAPD SET CAPD.Is_Active = 1
WHERE CAPD.Per_Id IN (
SELECT CAMP.Id
FROM CAMP
INNER JOIN CAPD ON (
CAPD.Per_Id = CAMP.Id
AND CAPD.Is_Active = 0
)
INNER JOIN CAD ON (
CAD.Id = CAPD.Deploy_Id
AND BINARY CAD.Access_Id = "486579446F6E277-4436F6E7665727449742E2E4C-4F4C203A5020584F586F"
)
WHERE CAMP.Serial = "ABC1230071"
)
You cannot use the target table which you are updating inside the
subquery. You need to use the JOIN in case you want to use it -- First
answer by #Rahul Tripathi
You have to try this query then you need to set SET SQL_SAFE_UPDATES
SET SQL_SAFE_UPDATES=0;
UPDATE CAPD
INNER JOIN CAD ON ( CAD.Id = CAPD.Deploy_Id)
SET CAPD.Is_Active = 1
WHERE CAPD.Per_Id IN (
SELECT CAMP.Id
FROM CAMP
WHERE CAMP.Serial = "ABC1230071"
)
AND BINARY CAD.Access_Id = "486579446F6E277-4436F6E7665727449742E2E4C-4F4C203A5020584F586F";
SET SQL_SAFE_UPDATES=1;
You cannot use the target table which you are updating inside the subquery. You need to use the JOIN in case you want to use it. Try like this:
UPDATE CAPD
INNER JOIN CAD ON ( CAD.Id = CAPD.Deploy_Id)
SET CAPD.Is_Active = 1
WHERE CAPD.Per_Id IN (SELECT CAMP.Id
FROM CAMP
WHERE CAMP.Serial = "ABC1230071" )
and CAD.Access_Id = "486579446F6E277-4436F6E7665727449742E2E4C-4F4C203A5020584F586F"
and CAPD.Is_Active = 0
The following is the MS Sql server Update statement
Update
HC_TranDetails
SET
InsPayments = (SELECT IsNull(SUM(ISNULL(CreditAmount,0)),0) From HC_TranDetails TDS
Where TDS.TransactionType = 2
AND TDS.ClaimNo = TD.ClaimNo
AND TDS.LineItemNo = TD.LineItemNo
AND IsNull(TDS.InsPlanRowID,'') <> ''
AND TDS.ReverseEntry <> 1 ),
Adjustments = (SELECT IsNull(SUM(ISNULL(CreditAmount,0)),0) From HC_TranDetails TDS
Where TDS.TransactionType = 8
AND TDS.ClaimNo = TD.ClaimNo
AND TDS.LineItemNo = TD.LineItemNo
AND IsNull(TDS.InsPlanRowID,'') <> ''
AND TDS.ReverseEntry <> 1 ),
FROM
HC_TranDetails TD
Now i am trying the same kind of statement in mysql as follows
UPDATE claimdetails SET balanceAmount = (SELECT IFNULL(SUM(IFNULL(debitamount,0)) - SUM(IFNULL(creditamount,0)),0)
FROM claimdetail CD WHERE CD.claimID = CDS.claimID)
FROM ClaimDetail CDS
But it is showing as syntax Error near 'From ClaimDetail CDS' at line 4
MySQL is squeamish about updates on the same table. The easy fix is to include an extra level of subquery. The proper fix, though, is to use a join
UPDATE claimdetails join
(select claimid, IFNULL(SUM(IFNULL(debitamount,0)) - SUM(IFNULL(creditamount,0)),0) as val
from ClaimDetails
group by claimid
) agg
on claimdetails.claimid = agg.claimid
SET balanceAmount = agg.val;
You can join the table you want to update with a subquery that calculates the balance for each claimid on the other table.
By using LEFT JOIN, it will update all records on table claimdetails. A value of 0 will be updated to any non existent claimid on the subquery.
UPDATE claimdetails a
LEFT JOIN
(
SELECT claimID,
SUM(IFNULL(debitamount, 0)) - SUM(IFNULL(creditamount,0)) bal
FROM claimdetail
GROUP BY claimID
) b ON a.claimID = b.claimID
SET a.balanceAmount = IFNULL(b.bal, 0)
I have a master table called "parent" and a related table called "childs"
Now I run a query against the master table to update some values with the sum from the child table like this.
UPDATE master m SET
quantity1 = (SELECT SUM(quantity1) FROM childs c WHERE c.master_id = m.id),
quantity2 = (SELECT SUM(quantity2) FROM childs c WHERE c.master_id = m.id),
count = (SELECT COUNT(*) FROM childs c WHERE c.master_id = m.id)
WHERE master_id = 666;
Which works as expected but is not a good style because I basically make multiple SELECT querys on the same result. Is there a way to optimize that? (Making a query first and storing the values is not an option.
I tried this:
UPDATE master m SET (quantity1, quantity2, count) = (
SELECT SUM(quantity1), SUM(quantity2), COUNT(*)
FROM childs c WHERE c.master_id = m.id
) WHERE master_id = 666;
but that doesn't work.
Update: Here is the solution, thanks to everbody:
You can do something like this:
UPDATE master m
INNER JOIN childs c ON m.master_id = c.master_id
SET master.quantity1 = c.quantity1,
master.count = 1
If you have only one child record at a time. However if you want to use a group function like SUM() in the joined table that doesn't work. Either you get a "Invalid use of group function" if you leave the "group by" part or a "You have an error in your sql syntax if you use "GROUP BY c.master_id"
-- This doesnt work :(
UPDATE master m
INNER JOIN childs c ON m.master_id = c.master_id
SET master.quantity1 = SUM(c.quantity1),
master.count = COUNT(c.*)
GROUP by c.master_id
The solution is to use JOIN with a subquery:
UPDATE master m
INNER JOIN
(
SELECT master_id,
SUM(quantity1) as quantity1,
COUNT(*) as count
FROM childs c
GROUP BY master_id
) c
ON c.master_id = m.master_id
SET m.quantity1 = c.quantity1,
m.count = c.count
WHERE m.master_id = 666;
But since this pulls every row from the childtable the overhead would likely be bigger than using more subqueries like in the original sql. So you should add a WHERE clause to the joined table to get only the rows you need.
Another interesting approach is this syntax, which does the same as the JOIN with the WHERE clause but you should only use if if you want to update all rows with the same values and your subquery only returns one row, since the result from the subquery gets appended to the result and can be used like any column.
UPDATE master m,
(
SELECT SUM(c.quantity1) as sum_of_quantity,
COUNT(*) as rowcount FROM child c WHERE c.master_id = 666
) as c
SET m.quantity1 = c.sum_of_quantity,
m.count = c.rowcount
WHERE m.master_id = 666;
Rewriting Lieven's solution to MySQL:
UPDATE master m
JOIN (
SELECT master_id
, SUM(quantity1) as quantity1
, SUM(quantity2) as quantity2
, COUNT(*) as count
FROM childs c
GROUP BY
master_id
) c
ON c.master_id = m.master_id
SET
m.quantity1 = c.quantity1
,m.quantity2 = c.quantity2
,m.count = c.count
WHERE m.master_id = 666;
I don't know if it is allowed in MySQL, but SQL Server allows you to use the result of a select in an update.
UPDATE master m SET
quantity1 = c.quantity1
, quantity2 = c.quantity2
, count = c.count
FROM master m
INNER JOIN (
SELECT master_id
, quantity1 = SUM(quantity1)
, quantity2 = SUM(quantity2)
, count = COUNT(*)
FROM childs c
WHERE master_id = 666
GROUP BY
master_id
) c ON c.master_id = m.master_id
You could select your data into a temporary table, and then update using that data.
If you also want to insert "new" data in the same roundtrip, look into INSERT INTO ... SELECT FROM ... ON DUPLICATE KEY UPDATE ...
If you already are doing inserts if row doesn't exist, then that would be redundant with this example.
example:
INSERT INTO master m (id, quantity1, quantity2, count)
SELECT master_id, SUM(quantity1) q1, SUM(quantity2) q1, COUNT(*) c
FROM childs
GROUP BY master_id
ON DUPLICATE KEY UPDATE
m.quantity1 = q1,
m.quantity2 = q2,
m.count = c
NOTE! This is untested code, but I think it should be possible to backreference the select result in the UPDATE.
Syntax reference: http://dev.mysql.com/doc/refman/5.0/en/insert.html