In my Mysql database I want to update a field fup for all records which I found using this select statement:
SELECT ic.hash
FROM incompany as ic, app
WHERE ic.id = app.ic_id;
So I created the following combined query:
UPDATE incompany
SET fup = 'x'
WHERE hash IN (SELECT ic.hash
FROM incompany as ic, app
WHERE ic.id = app.ic_id);
But this query gives me the following error:
You can't specify target table 'incompany' for update in FROM clause
Does anybody know how I can make this work? All tips are welcome!
You seem to want a condition on two columns, so this is a bit tricky. If I follow the logic correctly:
UPDATE incompany ic JOIN
(SELECT DISTINCT ic.hash
FROM incompany ic JOIN
app
ON ic.id = app.ic_id
) ica
ON ica.hash = ic.hash
SET fup = 'x' ;
You do not need a subquery. You might use INNER JOIN to set the criteria to link the incompany table to the app table and to the another alias for incompany table.
UPDATE incompany I
INNER JOIN app A ON I.id = A.ic_id
INNER JOIN incompany I2 ON I.hash = I2.hash
SET I.fup = 'x'
Related
I have a query:
SELECT assets.serial, employees.uid from assets
inner join emp_as on assets.serial = emp_as.serial
inner join employees on concat(emp_as.first_name,emp_as.last_name) = concat(employees.first_name,employees.last_name)
That returns two columns, an asset serial (unique) and an employee ID. I want to update the assets.employee_id field to be the select.employee_id where the asset.serial = select.serial (select being pseudocode for the result from that query).
Without seeing your database, I can't be 100% sure this is what you want, but I believe this should work. Mysql is very kind about allowing updates on joins so you don't need to worry about creating a temp table or a subquery.
update assets
join emp_as on assets.serial = emp_as.serial
join employees on concat(emp_as.first_name,emp_as.last_name) = concat(employees.first_name,employees.last_name)
set assets.employee_id = employees.uid
This should do the job:
UPDATE assets set assets.employee_id = employees.uid
inner join emp_as on assets.serial = emp_as.serial
inner join employees on concat(emp_as.first_name,emp_as.last_name) = concat(employees.first_name,employees.last_name)
I have the following query which selects personal messages (PM) from "ac_pms" table. Additional info is fetching from other table - "ac_accounts" using LEFT JOIN. There is "pm_read" column in "ac_pms" table which define a PM is read or not. I need to set that field (pm_read) to "1" while selecting PMs.
SELECT p.*, a.seller_id, a.winner_id
FROM `ac_pms` AS p
LEFT JOIN `ac_accounts` AS a ON p.pm_for_lot = a.id
WHERE (p.pm_from=[user_id] OR p.pm_to=[user_id])
AND p.pm_for_lot=[account_id]
ORDER BY p.pm_date DESC;
I cannot imagine where to insert UPDATE expression to SET pm_read = 1.
You can't SELECT with UPDATE in the same SQL statement.
However, you can UPDATE with JOIN like this:
UPDATE ac_pms AS p
LEFT JOIN ac_accounts AS a ON p.pm_for_lot = a.id
SET p.pm_read = 1
WHERE (p.pm_from=[user_id] OR p.pm_to=[user_id])
AND p.pm_for_lot = [account_id];
Then you can make another SELECT after that.
This is the select statement which i have got the correct answer:
select s_billing_cycle.Billing_cycle from s_billing_cycle
join o_daily_lcsgeneration_copy on o_daily_lcsgeneration_copy.Location=s_billing_cycle.Location where o_daily_lcsgeneration_copy.Date between s_billing_cycle.From_Date and s_billing_cycle.To_Date
while updating the same query into another table i couldnt do that using update query getting :
You cant update target table "o_daily_lcsgeneration_copy" for update in FROM Clause
the query i have used is :
update o_daily_lcsgeneration_copy set o_daily_lcsgeneration_copy.Billing_cycle = (select s_billing_cycle.Billing_cycle from s_billing_cycle join o_daily_lcsgeneration_copy on o_daily_lcsgeneration_copy.Location=s_billing_cycle.Location where o_daily_lcsgeneration_copy.Date between s_billing_cycle.From_Date and s_billing_cycle.To_Date)
Help me !!!
wrap it in a subquery (thus creating temporary table)
UPDATE o_daily_lcsgeneration_copy
SET o_daily_lcsgeneration_copy.Billing_cycle =
(
SELECT Billing_cycle
FROM
(
SELECT s_billing_cycle.Billing_cycle
FROM s_billing_cycle
INNER JOIN o_daily_lcsgeneration_copy
ON o_daily_lcsgeneration_copy.Location = s_billing_cycle.Location
WHERE o_daily_lcsgeneration_copy.DATE BETWEEN s_billing_cycle.From_Date
AND s_billing_cycle.To_Date
) s
)
or JOIN the tables
UPDATE o_daily_lcsgeneration_copy a
INNER JOIN s_billing_cycle b
ON a.Location = b.Location
SET a.Billing_cycle = b.Billing_cycle
WHERE a.DATE BETWEEN b.From_Date AND b.To_Date
The following query returns 2303 rows:
SELECT a.*
FROM cur_analises a
INNER JOIN cur_materias_subsidiarias ms
ON ms.materia_id = a.materia_id
AND ms.subsidiaria_id IN(SELECT id FROM cur_subsidiarias WHERE cliente_id = 134)
INNER JOIN cur_materias m
ON m.id = a.materia_id
INNER JOIN cur_clientes c
ON c.carga_id = ms.subsidiaria_id
WHERE a.cliente_id = 134;
I need to update the cliente_id field of all those 2303 rows from table cur_analises with the value from cur_clientes.id. However, when I try to turn that SELECT query into the following UPDATE, it only affects 2297 rows, according to MySQL Workbench:
UPDATE cur_analises a
INNER JOIN cur_materias_subsidiarias ms
ON ms.materia_id = a.materia_id
AND ms.subsidiaria_id IN(SELECT id FROM cur_subsidiarias WHERE cliente_id = 134)
INNER JOIN cur_materias m
ON m.id = a.materia_id
INNER JOIN cur_clientes c
ON c.carga_id = ms.subsidiaria_id
SET a.cliente_id = c.id
WHERE a.cliente_id = 134;
I have no idea why it's missing 6 rows. What am I doing wrong?
You are probably not joining on a unique value or set of values at some point in the query causing denormalization of your result set. Then when you do the update it only updates the rows that actually meet the criteria of the joins for the table aliased as a. Only you can know what are truly non denormalizing joins in your query and fix them.
We had a similar case, the issue was with mysql partitioning. Once we revert partitioning everything is ok again.
I am trying to create an update query and making little progress in getting the right syntax.
The following query is working:
SELECT t.Index1, t.Index2, COUNT( m.EventType )
FROM Table t
LEFT JOIN MEvents m ON
(m.Index1 = t.Index1 AND
m.Index2 = t.Index2 AND
(m.EventType = 'A' OR m.EventType = 'B')
)
WHERE (t.SpecialEventCount IS NULL)
GROUP BY t.Index1, t.Index2
It creates a list of triplets Index1,Index2,EventCounts.
It only does this for case where t.SpecialEventCount is NULL. The update query I am trying to write should set this SpecialEventCount to that count, i.e. COUNT(m.EventType) in the query above. This number could be 0 or any positive number (hence the left join). Index1 and Index2 together are unique in Table t and they are used to identify events in MEvent.
How do I have to modify the select query to become an update query? I.e. something like
UPDATE Table SET SpecialEventCount=COUNT(m.EventType).....
but I am confused what to put where and have failed with numerous different guesses.
I take it that (Index1, Index2) is a unique key on Table, otherwise I would expect the reference to t.SpecialEventCount to result in an error.
Edited query to use subquery as it didn't work using GROUP BY
UPDATE
Table AS t
LEFT JOIN (
SELECT
Index1,
Index2,
COUNT(EventType) AS NumEvents
FROM
MEvents
WHERE
EventType = 'A' OR EventType = 'B'
GROUP BY
Index1,
Index2
) AS m ON
m.Index1 = t.Index1 AND
m.Index2 = t.Index2
SET
t.SpecialEventCount = m.NumEvents
WHERE
t.SpecialEventCount IS NULL
Doing a left join with a subquery will generate a giant
temporary table in-memory that will have no indexes.
For updates, try avoiding joins and using correlated
subqueries instead:
UPDATE
Table AS t
SET
t.SpecialEventCount = (
SELECT COUNT(m.EventType)
FROM MEvents m
WHERE m.EventType in ('A','B')
AND m.Index1 = t.Index1
AND m.Index2 = t.Index2
)
WHERE
t.SpecialEventCount IS NULL
Do some profiling, but this can be significantly faster in some cases.
my example
update card_crowd as cardCrowd
LEFT JOIN
(
select cc.id , count(1) as num
from card_crowd cc LEFT JOIN
card_crowd_r ccr on cc.id = ccr.crowd_id
group by cc.id
) as tt
on cardCrowd.id = tt.id
set cardCrowd.join_num = tt.num;