MYSQL : IF EXISTS - mysql

I am trying to update a table called jdwf_orders_main if the value of jaj_jno is present in jdwf_alien_jobs table.
I am trying to do it using IF EXISTS but I can't seem to get the syntax right.
What is wrong with my syntax.
IF ( EXISTS (SELECT * from jdwf_alien_jobs where jaj_jno = '7200000') ,
UPDATE jdwf_orders_main set jom_adv_name = 'IAM OP' where jom_job_no = '7200000',
UPDATE jdwf_orders_main set jom_adv_name = 'IAM Noob' where jom_job_no = '7200000');

MySQL does not support the operation you tried. It provides another way to get the same result: update two or more joined tables in a single UPDATE query.
I cannot test but somethings like this should work:
UPDATE jdwf_orders_main om
LEFT JOIN from jdwf_alien_jobs aj ON om.jom_job_no = aj.jaj_jno
SET om.jom_adv_name = IF(af.jaj_no IS NULL, 'IAM Noob', 'IAM OP')
WHERE om.jom_job_no = '7200000'
How it works
It joins the table jdwf_orders_main (aliased as om) with jdwf_alien_jobs (aliased as aj) on the om.jom_job_no = aj.jaj_jno condition.
The LEFT JOIN ensures all the rows from the left table (om) appear in the result set; if a row does not have a matching row in the right table, a row full of NULLs is used for the fields of the right table.
The WHERE clause filters only the rows that match the condition om.jom_job_no = '7200000' to be modified by the UPDATE statement.
The SET clause updates om.jom_adv_name (i.e. the column jom_adv_name from the jdwf_orders_main table) with the value computed by the IF() function.
The IF() function returns 'IAM Noob' if af.jaj_jno is NULL. This happens when for the row from om does not exist any matching row in af (see the explanation of the LEFT JOIN clause above). Otherwise (when a matching row exists), af.jaj_jno is not NULL and the IF() function returns 'IAM OP'.

Related

mysql: I want to sum up all the values of credit from table semester and then add to another column total_credit from another table

I have the below code:
UPDATE VIEW
LEFT JOIN sem_view ON (view.semester = sem_view.semester)
SET view.t_credit = SUM(sem_view.credit)
but its not working saying invalid use of group
Data for updating must be perpared previously, in subquery. Updating must use the data which is already aggregated.
Left joining may be errorneous - it will set the value in the destination table to NULL if according data for the semester in interest in sem_view is not present. But if the logic needs this then you may use LEFT JOIN instead of INNER one in the below query.
Totally:
UPDATE `view`
JOIN ( SELECT sem_view.semester, SUM(sem_view.credit) summ
FROM sem_view
GROUP BY sem_view.semester ) data_for_updating
ON `view`.semester = data_for_updating.semester
SET `view`.t_credit = data_for_updating.summ;
PS. The text looks like view is a name of a table to be updated.

Unify and simplify MySQL commands

I did some MySQL commands, however it was a bit slow to execute because there are three commands executed at the same time.
How can I unite all in just one command and simplify the code to make it faster?
UPDATE bidbutler b
LEFT JOIN auction a on b.auc_id=a.auctionID
LEFT JOIN auc_due_table c on b.auc_id=c.auction_id
SET b.butler_status=0
WHERE b.auc_id=a.auctionID
AND b.auc_id=c.auction_id
AND b.butler_status<>0
AND a.auc_status=3
AND c.auc_due_price<>a.auc_final_price
AND c.auc_due_time=a.total_time;
DELETE t1
FROM won_auctions t1
LEFT JOIN auc_due_table t2 ON t1.auction_id = t2.auction_id
LEFT JOIN auction t3 ON t1.auction_id = t3.auctionID
WHERE t1.auction_id = t2.auction_id
AND t1.auction_id = t3.auctionID
AND t2.auc_due_price<>t3.auc_final_price
AND t2.auc_due_time=t3.total_time
AND t3.auc_status=3;
UPDATE auction a
LEFT JOIN auc_due_table b on a.auctionID=b.auction_id
SET a.auc_status=2
WHERE a.auc_status=3
AND a.auctionID=a.auctionID
AND b.auc_due_price<>a.auc_final_price
AND b.auc_due_time=a.total_time;
The three commands will be executed at the same time through a database procedure, which is executed every second by an event.
NEW DELETE UPDATED:
DELETE t1
FROM won_auctions t1
JOIN auction t2
ON t1.auction_id = t2.auctionID
LEFT JOIN auc_due_table t3
ON t3.auction_id = t1.auction_id
AND t3.auction_id = t2.auctionID
AND t3.auc_due_price<>t2.auc_final_price
AND t3.auc_due_time=t2.total_time
WHERE t2.auc_status=3;
preamble
repeating notes I left as a comment on the question, because I'm not sure there was enough emphasis placed on these points:
"I don't think the slowness is due to three separate statements."
"It looks like the statements have the potential to churn through a lot of rows, even with appropriate indexes defined."
"Use EXPLAIN to see the execution plan, and ensure suitable indexes are being used, ..."
answer
The DELETE statement can't be combined with an UPDATE statement. SQL doesn't work like that.
It might be possible to combine the two UPDATE statements, if those are visiting the same rows, and the conditions are the same, and the second UPDATE is not dependent on the preceding UPDATE and DELETE statement.
We see the first UPDATE statement requires a matching row from bidbutler table. The second UPDATE statement has no such requirement.
We notice that the predicates in the WHERE clause are negating the "outerness" of the LEFT JOIN. If the original statements are correctly implemented (and are performing the required operation), then we can eliminate the LEFT keyword.)
We also find a condition a.auctionID=a.auctionID which boils down to a.auctionID IS NOT NULL. We already have other conditions that require a.auctionID to be non-NULL. (Why is that condition included in the statement?)
We also see a condition repeated: b.auc_id=c.auction_id appearing in both the ON clause and the WHERE clause. That condition only needs to be specified once. (Why is it written like that? Maybe something else was intended?)
The first UPDATE statement could be rewritten into the equivalent:
UPDATE auction a
JOIN auc_due_table d
ON d.auction_id = a.auctionID
AND d.auc_due_time = a.total_time
AND d.auc_due_price <> a.auc_final_price
LEFT
JOIN bidbutler b
ON b.auc_id = a.auctionID
AND b.auc_id = d.auction_id
AND b.butler_status <> 0
SET b.butler_status = 0
WHERE a.auc_status = 3
The second UPDATE statement can be rewritten into an equivalent:
UPDATE auction a
JOIN auc_due_table d
ON d.auction_id = a.auctionID
AND d.auc_due_time = a.total_time
AND d.auc_due_price <> a.auc_final_price
SET a.auc_status = 2
WHERE a.auc_status = 3
The difference is the extra outer join to bidbutler table, and the SET clause.
But before we combine these, we need to decipher whether the operations performed in the first UPDATE or the DELETE statement) influence the second UPDATE statement. (If we run these statements in a different order, do we get a different outcome?)
A simple example to illustrate the type of dependency we're trying to uncover:
UPDATE foo SET foo.bar = 1 WHERE foo.bar = 0;
DELETE foo.* FROM foo WHERE foo.bar = 0;
UPDATE foo SET foo.qux = 2 WHERE foo.bar = 1;
In the example, we see that the outcome is (potentially) dependent on the order the statements are executed. The first UPDATE statement will modify the rows that won't be removed by the DELETE. If we were to run the DELETE first, that would remove rows that would have been updated... the order the statements are executed influence the result.
Back to the original statements in the question. We see auc_status column being set, but also a condition on the same column.
If there are no dependencies between the statements, then we could re-write the two UPDATE statements into a single statement:
UPDATE auction a
JOIN auc_due_table d
ON d.auction_id = a.auctionID
AND d.auc_due_time = a.total_time
AND d.auc_due_price <> a.auc_final_price
LEFT
JOIN bidbutler b
ON b.auc_id = a.auctionID
AND b.auc_id = d.auction_id
AND b.butler_status <> 0
SET b.butler_status = 0
, a.auc_status = 2
WHERE a.auc_status = 3

Ambiguous column name in update's where statement

I have one result table and two source tables. One source have same column name for key as result table, and second one have slightly different (same values, just different column name).
So if i use code as:
--Works
Update new_table set new_column_1 = source_column_1
from new_table t0
Left join source_table_1 t1
On t0.key_column = t1.id_column
Where key_column = t0.key_column
--Don't
Update new_table set new_column_2 = source_column_2
from new_table t0
Left join source_table_2 t1
On t0.key_column = t1.key_column
Where key_column = t0.key_column
2nd example would give me "Ambiguous column name" error in Where statement. (1st key_column should belong to update destination, 2nd to update source)
I manage around that problem by wrapping source for update into subquery which would rename key column into something else, but i'm curious why that happens in a first place. How come that key names for join make effect on where clause?
You must use the alias since both table have a column named key_column.
This query should work:
Update t0 set new_column_2 = t1.source_column_2 -- or t0.source_column_2?
from new_table t0
Left join source_table_2 t1
On t0.key_column = t1.key_column
Where t1.key_column = t0.key_column
The alias will replace the table name between update and set.
But the where clause does not seem necessary. It is identical to the ON clause. A INNER JOIN would be more appropriate here.

USING IF with UPDATE MYSQL

Im trying to do an update with a IF function
IF(SELECT 'FUNCION' FROM tickets
WHERE (FUNCION = COR) AND (tickets.CLIENTE=clientes.CLIENTE))
THEN UPDATE `clientes` SET `ESTADO` = 'I';
I tried this but it seems I have a syntax error.
How can I get this to work?
EDIT: I want to update 'ESTADO' to 'I' if 'FUNCION', from another table, is 'COR' and the fields 'CLIENTE' match each other.
You can use a join operation in an UPDATE statement.
It's not clear to me what COR is a reference to, so I'm going to assume it's supposed to be a string literal, not a reference to a column name.
Here's an example:
UPDATE clientes c
JOIN tickets t
ON t.cliente = c.cliente
AND t.funcion = 'COR'
SET c.estado = 'I'
That says, find all rows in clientes that have a "matching" row in tickets, and set the estado column to 'I' on those rows.
Think about it this way... write a SELECT query first to identify the rows you want to update, and filter out the ones you don't.
SELECT c.* -- please don't use * in code in applications!
, t.funcion
FROM clientes c
JOIN tickets t
ON t.cliente = c.cliente
AND t.funcion = 'COR'
--or--
SELECT c.*
FROM clientes c
WHERE EXISTS ( SELECT 1
FROM tickets t
WHERE t.cliente = c.cliente
AND t.funcion = 'COR'
)
Once you have a SELECT statement working (that retrieves ONLY the rows you want to update), you can convert that into an UPDATE, by replacing SELECT ... FROM with the keyword UPDATE, and add a SET clause before the WHERE clause.
There's also some "tricks" we can play in the expression in the SET, to do some conditional assignment. To leave the column unchanged, assign the current value back to the column.
For example, to replace only NULL values of estado
SET c.estado = IF(c.estado IS NULL,'I',c.estado)
If the boolean expression (first argument in the IF() function) evaluates to TRUE, then return the result of the evaluation of the second argument (in this example 'I'), otherwise, return the current value of the estado column.
That's not how you write a conditional update. Use a where clause:
UPDATE clientes
SET estado='I'
WHERE (funcion = cor) AND (tickets.client=clients.cliente)
This won't work, since you're referring to fields/tables that aren't joined into the query.

Not working an Update query as I wish

Hi I want to update a table with the values of another but do not how to do it.
I have tried this but it is not working.
UPDATE tblagendamiento SET
CodigoAgenda =
(select tmptable.CodigoCita from tmptable where tmptable.id = tblagendamiento.id);
And this is the error:
Subquery returns more than 1 row
You are actually getting an error because your subquery is returning more than one row. I think you can achieve this simply using an INNER JOIN query
UPDATE tblagendamiento a
INNER JOIN tmptable b
ON a.id = b.id
SET a.CodigoAgenda = b.CodigoCita
The message is telling you that there is more than one row returned by your subquery. Assuming you don't want to use a random value (which you can do by appending limit 1 to the query), it means your where clause is not selective enough.