How to execute update join query? - mysql

How do we run these types of queries in MySQL?
How to execute these types of queries how we run in MySQL, i.e. update join query?
UPDATE file_master t1,users t2 SET
t1.Status = "cancel",
t1.is_credit_revers=1,
t1.is_credit_reversed=1,
t1.t_reversal=t1.credit,
t2.credit=t1.credit+
(
select sum(t1.credit) from file_master where FileID in(7,6,5)
)
WHERE t1.FileID in(7,6,5)
and t1.CRN=t2.id
and t1.CRN=1 ;
1093 - Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data

MySQL objects to updating a table which is also in a sub query
You can sometimes hide the sub query within another sub query to get around this.
As such try something like this:-
UPDATE file_master t1
INNER JOIN users t2
ON t1.CRN = t2.id
CROSS JOIN
(
SELECT credit_sum
FROM
(
SELECT SUM(credit) AS credit_sum
FROM file_master
WHERE FileID IN(7,6,5)
) t3
) t4
SET t1.Status = "cancel",
t1.is_credit_revers = 1,
t1.is_credit_reversed = 1,
t1.t_reversal = t1.credit,
t2.credit = t1.credit + t4.credit_sum
WHERE t1.FileID in(7,6,5)
AND t1.CRN = 1 ;

Related

How can I optimize this MySQL query in a stored procedure?

SET #count := (SELECT count(*)
FROM dbo.ManyToManyTable SRSG
JOIN tableA SG on SRSG.a = SG.a
JOIN tableB SR on SRSG.b = SR.a
WHERE SR.c = INPUT_VALUE);
IF (#count > 0)
THEN
SELECT SG.fieldA, SG.fieldB
FROM dbo.ManyToManyTable SRSG
JOIN tableA SG on SRSG.a = SG.a
JOIN tableB SR on SRSG.b = SR.a
WHERE SR.c = INPUT_VALUE;
ELSE
SELECT SG.a, SG.b FROM dbo.tableA SG WHERE SG.b = "default value";
END IF;
It's for a MySQL database. This works for me, but I don't like the duplicate select query. However, I have no idea how to fix it under the constraint which is the logic has be within one stored procedure.
You could write this as a single query:
with cte as (
SELECT SG.fieldA, SG.fieldB
FROM dbo.ManyToManyTable SRSG JOIN
tableA SG
on SRSG.salesGroupId = SG.salesGroupId JOIN
tableB SR
on SRSG.salesRegionId = SR.salesRegionId
WHERE SR.AField = INPUT_VALUE
)
select *
from cte
union all
select SG.a, SG.b
from dbo.tableA SG
where SG.b = 'default value' and
not exists (select 1 from cte);
MySQL tends to materialize CTEs (always?), so this should run the query once rather than twice.
A quick, but partial speedup is to replace
SET #count = ( SELECT COUNT(*) ... );
IF (#count > 0)
with this (using the rest of that initial SELECT):
IF ( EXISTS ( SELECT 1 FROM ... ) )
Also for performance, be sure to have in SRSG:
PRIMARY KEY(a,b)
INDEX(b,a)
and don't bother with an AUTO_INCREMENT.

MySQL UPDATE TABLE with subquery does not execute subquery first

I have a query that produces 3 columns (ApplicationID, FamilySize, GrantID). In the initial query FamilySize is a count. The query works, takes about 5 minutes to produce results, and produces expected results. The query is as such:
SELECT t1.ApplicationID, COUNT(*) FamilySize, t1.GrantID
FROM
(
SELECT g.ApplicationID, ChildApplicationID `RefID`, g.GrantID
FROM CONTINUITYCHILD_P `child`
JOIN uspto.GRANT as g ON child.ApplicationID = g.ApplicationID
UNION
SELECT g2.ApplicationID, ParentApplicationID `RefID`, g2.GrantID
FROM CONTINUITYPARENT_P `par`
JOIN uspto.GRANT as g2 ON par.ApplicationID = g2.ApplicationID
) t1
GROUP BY ApplicationID
That initial query works fine. However, I want to use it to update a field in another table Where the GrantID match. I'm using MariaDB but looked at the MySQL 8 documentation since MariaDB and MySQL are supposed to have compatible syntax: https://dev.mysql.com/doc/refman/8.0/en/update.html
I am trying to use the syntax similar to this:
UPDATE t1, t2
SET t1.column = t2.column
WHERE t1.column2 = t2.column2
So that would convert my entire initial query into a table (t2) and the table being updated (t1) would be able to match on a column between t1 and t2.
This is the resulting query:
UPDATE METRICS_G m,
(
SELECT ApplicationID, COUNT(*) FamilySize, GrantID
FROM
(
SELECT g.ApplicationID, ChildApplicationID `RefID`, g.GrantID
FROM CONTINUITYCHILD_P `child`
JOIN uspto.GRANT as g ON child.ApplicationID = g.ApplicationID
UNION
SELECT g2.ApplicationID, ParentApplicationID `RefID`, g2.GrantID
FROM CONTINUITYPARENT_P `par`
JOIN uspto.GRANT as g2 ON par.ApplicationID = g2.ApplicationID
) t1
GROUP BY ApplicationID
) t2
SET m.FamilySize = t2.FamilySize
WHERE m.GrantID = t2.GrantID;
The query gives no errors, and returns in 3ms with 0 rows affected.
This must mean that the sub-query is not being executed since it will normally take a few minutes for that query to return.
What have I done wrong to use the output of a query as a table to match in an UPDATE statement?
You must join the query to the table METRICS_G in the UPDATE statement:
UPDATE METRICS_G m
INNER JOIN (
SELECT ApplicationID, COUNT(*) FamilySize, GrantID
FROM (
SELECT g.ApplicationID, ChildApplicationID `RefID`, g.GrantID
FROM CONTINUITYCHILD_P `child`
JOIN uspto.GRANT as g ON child.ApplicationID = g.ApplicationID
UNION
SELECT g2.ApplicationID, ParentApplicationID `RefID`, g2.GrantID
FROM CONTINUITYPARENT_P `par`
JOIN uspto.GRANT as g2 ON par.ApplicationID = g2.ApplicationID
) t1
GROUP BY ApplicationID
) t2 ON m.GrantID = t2.GrantID
SET m.FamilySize = t2.FamilySize

SQL: update a record if a certain kind of a record is not in the same table

I want to update a certain record of a table only if certain another record does not already exist in the table.
I tried a SQL similar to following.
update mytable
set val = 'someval'
where id = 'someid' and
0 = (select count(*) from mytable where col='val2');
This fails with following error.
You can't specify target table 'mytable' for update in FROM clause
Only one process is updating this table, so preserving the atomicity of the operation is not necessary.
I know I can do this using two SQL queries, but is there a way to do this in a single query?
Because you are referring to the same table, the best way to do this uses LEFT JOIN:
update mytable t left join
mytable t2
on t2.col = 'val2'
set val = 'someval'
where t.id = 'someid' and t2.col is null;
There are several ways to do this. Here's one option using a subquery with not exists:
update mytable
set val = 'someval'
where id = 'someid'
and not exists (
select 1
from (select * from mytable) t
where col = 'val2')
SQL Fiddle Demo
Using the subquery bypasses the error you are receiving. Other approaches include outer join with null checks or using not in -- depends a bit on the data.
TRY this:
UPDATE mytable SET val = 'someval'
WHERE id = 'someid' AND col <> 'val2'

Incorrect usage of UPDATE and LIMIT

When I execute the following query:
UPDATE `table1`
INNER JOIN Address ON Address.Mobile = table1.number
LEFT JOIN tps ON tps.number = table1.number
SET table1.export = '2015-03-31'
WHERE Address.Surname != '' and tps.number is null AND table1.export = '0000-00-00'
limit 100000
I get error:
Incorrect usage of UPDATE and LIMIT
I need to use Limit when using Update join. How to solve this issue?
Think it is objecting to the use of order / limit on a multi table update statement.
I would suggest trying to to do an update where the key field is in the results of a sub query that returns the limited set of records. One problem here is that MySQL will not allow you to update a table that is also in the sub query, but you can normally get around this by having a 2nd containing sub query.
Something like this:-
UPDATE table1
SET table1.export = '2015-03-31'
WHERE table1.number IN
(
SELECT number
FROM
(
SELECT table1.number
FROM `table1`
INNER JOIN Address ON Address.Mobile = table1.number
LEFT JOIN tps ON tps.number = table1.number
WHERE Address.Surname != '' and tps.number is null AND table1.export = '0000-00-00'
limit 100000
) sub1
) sub2

MySql - Update table using select statment from same table

I'm trying to update row in a table using values from a different row (and different columns) in the same table. Something along the lines of this, although my syntax produces no results: Here is the code (updated):
UPDATE table1 AS t1 INNER JOIN
(SELECT field_id_46,field_id_47 FROM table1 WHERE entry_id = 36) AS t2
SET t1.field_id_60 = t2.field_id_46, t1.field_id_61 = t2.field_id_47
WHERE t1.entry_id = 45;
update table as t1
inner join (
select field_id_46,field_id_47 from table where entry_id = 36) as t2
set t1.field_id_60 = t2.field_id_46,
t1.field_id_61 = t2.field_id_47
where t1.entry_id = 45
or, simply
update table as t1,
(
select field_id_46,field_id_47 from table where entry_id = 36) as t2
set t1.field_id_60 = t2.field_id_46,
t1.field_id_61 = t2.field_id_47
where t1.entry_id = 45
Adding..
Same tables, with more of one registers
UPDATE table t1
INNER JOIN table t2 ON t2.entry_id = t1.entry_id
SET t1.field_id_60 = t2.field_id_60,
t1.field_id_61 = t2.field_id_61
You can update using inner join as follow :
UPDATE table1 AS t1
INNER JOIN table1 AS t2
SET t1.field_id_60 = t2.field_id_46,
t1.field_id_61 = t2.field_id_47
WHERE t1.entry_id = 54;
I found this question very useful because I was trying to insert into a table manually while that specific database was using a hibernate_sequence table.
I used the solution from this question to mod my import script.
I had a script with many "insert into" statements one after the other and I had to set the id manually. for example:
insert into T01_REGIONS (ID, NAME) VALUES ({the next id from hibernate_sequence}, 'name1');
insert into T01_REGIONS (ID, NAME) VALUES ({the next id from hibernate_sequence}, 'name2');
..
.
So what I did is the following to work around my problem:
insert into T01_REGIONS (ID, NAME) VALUES ((select next_val from hibernate_sequence limit 1), 'name1');update hibernate_sequence as t1, (select next_val+1 as next from hibernate_sequence limit 1) as t2 set t1.next_val = t2.next;
insert into T01_REGIONS (ID, NAME) VALUES ((select next_val from hibernate_sequence limit 1), 'name2');update hibernate_sequence as t1, (select next_val+1 as next from hibernate_sequence limit 1) as t2 set t1.next_val = t2.next;
..
.
Adding the extra query at the end of each line of my sql script was easy with notepad++. I know this might be very ugly but it did work for me in order to import data to a test hibernate operated mysql database while my data was coming from an oracle hibernate operated database.
You are not need to this query
SELECT field_id_46,field_id_47 FROM table WHERE entry_id = '36'
You should just do this:
UPDATE table SET (field_id_60,field_id_61) ('coming_value','other_value') WHERE entry_id = '45';
Also you can do this with 2 different coloumns.I think you can do like this.But It might i havent got any idea.You should split this query in which language do you use.In first method you should use this query.
SELECT field_id_46,field_id_47 FROM table WHERE entry_id = '36'
And You can also return String that is coming from this data.Then you can use this returned value in update function.