MySql Join Query Problem - mysql

I am trying to update all transaction_subcategory_id's in transaction to match_subcategory_id in match where match_name in match is the same as transaction_subcategory_name in transaction.
Its got to be simple, just not getting very far with it...
this is our latest attempt...
UPDATE transaction JOIN match ON match.match_name = transaction.transaction_name
SET transaction.transaction_subcategory_id = match.match_subcategory_id;
tables
match
--------------------------
match_id
match_name
match_subcategory_id
transaction
--------------------------
transaction_id
transaction_name
transaction_subcategory_id

UPDATE `transaction` SET `transaction`.`transaction_subcategory_id` = `match`.`match_subcategory_id`
JOIN `match` ON `match`.`match_name` = `transaction`.transaction_name;
Just switch the position of the SET and the JOIN and it should work.
MySQL Docs on UPDATE statement
The docs only show the implicit join:
UPDATE `transaction`, `match` SET `transaction`.`transaction_subcategory_id` = `match`.`match_subcategory_id`
WHERE `match`.`match_name` = `transaction`.`transaction_name`;
But they say you can use any JOIN syntax that works on SELECT on UPDATE, so your query should work when switching SET and JOIN.

try with SET before JOIN on your query

Related

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

MySQL Conditional Update in same table

I'm looking for a simple way to do an update on a table only if there is no other columns present in that same table with the same value I'm trying to update, ideally in a single query. So far I'm getting an error You specify target table 't1' for update in FROM clause. Here is what I tried in a few variations so far (still unable to get working):
UPDATE emailQueue AS t1
SET
t1.lockedOn = 1470053240
WHERE
(SELECT
COUNT(*)
FROM
emailQueue AS t2
WHERE
t2.lockedOn = 1470053240) = 0
AND t1.lockedOn IS NULL
In MySQL, you need to use a join. In this case, a left join is in order:
UPDATE emailQueue eq LEFT JOIN
emailQueue eq2
ON eq2.lockedOn = 1470053240
SET eq.lockedOn = 1470053240
WHERE eq.lockedOn IS NULL AND
eq2.lockedOn IS NULL;

MYSQL nested query running very slow?

The following query is constantly timing out, is there a less overhead way to achieve the same function ?
UPDATE Invoices SET ispaid = 0
WHERE Invoice_number IN (SELECT invoice_number
FROM payment_allocation
WHERE transactionID=305)
What I'm doing is unallocating invoices from a transaction, there can be up to 30+ records returned but it stops the database dead everytime I try to run it
USE JOIN instead of subquery it will improve the performance.
Create index on Invoice_number column in both table if you haven't created.
Try this:
UPDATE Invoices i
INNER JOIN payment_allocation pa ON i.Invoice_number = pa.invoice_number
SET i.ispaid = 0
WHERE pa.transactionID = 305;
I'd try EXISTS :
UPDATE Invoices a set ispaid=0
WHERE EXISTS
(
SELECT NULL FROM payment_allocation b
WHERE b.Invoice_number =a.Invoice_number AND b.transactionID=305
)
As of MySQL 5.5, Subquery Selects (another full select statement inside the query) cannot be optimized. This is probably why your query is so slow. Refactor you query to get rid of the inner select statement.
UPDATE Invoices, payment_allocation
SET ispaid=0
WHERE payment_allocation.transactionID=305 AND
Invoices.Invoice_number = payment_allocation.invoice_number
An interesting sidenote... But MariaDB (a branch of MySQL by the original creator) has implemented Subquery select optimization.
UPDATE invoices i
JOIN payment_allocation pa
ON pa.invoice_number = i.invoice_number
SET i.ispaid=0
WHERE pa.transactionID = 305;

update field with another field another table

I want to update a field in table1 with another field in table2.I wrote the following query but it is not working.
UPDATE tempdata A
SET A.new_user_id =
(SELECT B.id FROM user B
WHERE A.usr_email = B.usr_email)
It is giving "#1242 - Subquery returns more than 1 row" error. Anybody please help me.
UPDATE tempdata A, user B
SET A.new_user_id = B.id
WHERE A.usr_email = B.usr_email
you can still join tables even if it is an update statement.
UPDATE tempdata A
INNER JOIN user B
ON A.usr_email = B.usr_email
SET A.new_user_id = B.id
Beware that error means that in table user there are more than 1 rows with field usr_email equals to tempdata's one. Check for dupes before runniing the actual update statement with the LIMIT 1 a suggested by Salil
This is also one way to handle this scenerio
UPDATE A
SET A.new_user_id = B.id
FROM tempdata A
INNER JOIN user B ON A.usr_email = B.usr_email

mysql 3 table join with update

I am trying to update the status of a column, by checking two joined tables. Even though I dont get an error. The colum is not updating. I want to take the general blockplot id and see if there is a transaction that matches and or a a container. If there is a transaction but no container i need to mark it as P.
UPDATE (general
LEFT JOIN
transactions
ON
general.blockplotid=transactions.blockplotid)
LEFT JOIN
container
ON
general.blockplotid=container.blockplotid
SET general.lotstatus = 'P'
WHERE general.lotstatus != 'U' AND
transactions.id_transaction IS NOT NULL AND
container.id_container IS NULL
So summarize, I have 3 tables. I only want to update one colum in one table. I want to check for values in the other two tables, their values depend upon the set value. The three tables are connected with a primary key to foreign key.
When I do a double join select statement. The query seems correct.
SELECT transactions.blockplotid AS blockplotid_2, container.blockplotid AS blockplotid_1, general.blockplotid, general.lotstatus, container.id_container, transactions.id_transaction
FROM ((general LEFT JOIN transactions ON general.blockplotid=transactions.blockplotid) LEFT JOIN container ON general.blockplotid=container.blockplotid)
ORDER BY general.blockplotid ASC
However it seems as though the join for the update isnt like the select.
This query seemed to work:
This query worked:
UPDATE ((general LEFT JOIN transactions ON transactions.blockplotid=general.blockplotid) LEFT JOIN container ON container.blockplotid=general.blockplotid)
SET general.lotstatus='P'
WHERE general.blockplotid!='U' AND container.id_container is null AND transactions.id_transaction is not null
The difference here is the case of IS NOT NULL and also the order of the where condition.
Is there any explanation for this?
I suspect the parentheses/locations of the joins. Try a setup like this:
UPDATE
Table1
SET
Table1
. Field1 = StagingTable . Field1
FROM
Table1
INNER JOIN StagingTable
ON Table1 . Field2 = StagingTable . Field2
WHERE
StagingTable . Field3 IS NOT NULL
I would suggest restructuring your UPDATE statement to have an embedded SUB-SELECT. update general set lotstatus = (SELECT .... WHERE .... )