I've got two tables, we'll call them email_bounces and master_email_list.
master_email_list is ~3.5m records.
email_bounces is ~100,000 records.
I'm trying to do a query where I update bounce=1 in master_email_list if the email address is found in email_bounces.
Here's what I have.
update 'master_email_list' set bounce=1 where email in (select email FROM 'email_bounces')
Except that doesn't seem to work, it queries, then hangs indefinitely (I left it running overnight, after about 4 hours running prior).
Help is appreciated.
Use
update master_email_list l
inner join email_bounces b on b.email = l.email
set bounce = 1
You could also try to deactivate keys during the update to speed things up:
ALTER TABLE master_email_list DISABLE KEYS;
And afterwards
ALTER TABLE master_email_list ENABLE KEYS;
By using table alias names you have to set it.
In this i am using inner join
update master_email_list mel
inner join email_bounces eb
on mel.email = eb.email
set mel.bounce = 1
If that simple query takes hours, I can only see two possible reasons;
You're missing an index with master_email_list.email as a first column.
CREATE INDEX ix_email ON master_email_list(email);
...should speed things up significantly.
You have an active transaction on the table that holds a lock. Check that you have no uncommitted transactions pending, and if you can't find them, check this answer how to look for them.
Related
I found several questions with similar wording, but none addressed the specific question I have.
How does one perform an UPDATE with conditions that operate between two unlinked tables?
As example
TABLE_I
ID, Placed, junk, junk, junk
TABLE_II
ID, Category, Placed, Note, junk, junk...
If the Condition is in TABLE_II
WHERE Category=9 AND Note=#testvalue
An UPDATE should take place where a value in TABLE_II matches one in TABLE_I
UPDATE TABLE_I SET Placed=#testvalue WHERE
.. the Current TABLE_I.Placed=Table_II.Placed assuming the above conditions are met
Is such stepped-in conditioning even possible in SQL? Or would it require coding outside of the query to test in steps?
SQL
update t1 SET t1.Placed=#testvalue
from Table_1 t1
join Table_2 t2 on t1.placed = t2.placed
where t2.Category=9 AND t2.Note=#testvalue
you have to use join in the update statement
Mysql
the answer is yes you can
try it like that
update Table_1 t1
join Table_2 t2 on t1.placed = t2.placed
where t2.Category=9 AND t2.Note=#testvalue
SET t1.Placed=#testvalue
EDIT:
For general Update join :
UPDATE TABLEA a
JOIN TABLEB b ON a.join_colA = b.join_colB
SET a.columnToUpdate = [something]
You could do this kind of stuff with a trigger on insert on table_i combined with a procedure for updating the first table.
Not sure on how to do it in MySQL or SQL-server (why 2 tags? Which is it?), but it probably is not much different from doing this in PostgreSQL. A quick Google search gave me http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html
Though the best solution probably is to actually link the unlinked tables.
I have tried this many different ways but am getting errors strange results in all of them. I have a master table of transactions: Transactions and a query ArchiveDelete that finds new transactions from a temporary table based on the LastModifyDate. I'd like to delete transactions where ConfirmationNumber in Transactions = ConfirmationNumber in ArchiveDelete.
My first attempt was simple:
DELETE Transactions.*
FROM Transactions INNER JOIN ArchiveDelete ON Transactions.ConfirmationNumber = ArchiveDelete.ConfirmationNumber;
and I received an error: 'Could not delete from specified tables.' Clicking help is useless. I have full rights to the tables. I've attempted to Google the error and one suggestion was to run this instead:
DELETE Transactions.*
FROM Transactions Where Transactions.ConfirmationNumber in (Select ConfirmationNumber from ArchiveDelete)
But this takes forever and I don't have all day for a simple delete. There are only 183 transactions I need to remove.
I also tried the Delete using Exists here: How to delete in MS Access when using JOIN's?
DELETE Transactions.*
FROM Transactions
Where Exists(Select 1 from ArchiveDelete Where ArchiveDelete.ConfirmationNumber = Transactions.ConfirmationNumber) = True
But now it wants to delete all 47073 rows in my table, not just the 183 that match.
What am I doing wrong? Why is this so difficult?
I believe because ArchiveDelete is a query might be why you are having trouble. Try making a temporary table ArchiveDeleteTemp instead (at least to test) and using that instead.
DELETE Transactions.*
FROM Transactions INNER JOIN ArchiveDeleteTemp ON Transactions.ConfirmationNumber = ArchiveDeleteTemp.ConfirmationNumber;
I need to update some information which are stored in two tables. To update one of the table, a JOIN with the other table must be done. I was wondering, if I can update both with a single query. Some posts suggested using a trigger. I was hoping there's another way, since I will have to do it in C#. Also I saw other posts saying it's possible using something like this:
update pd, pr
set pd.Name = 'Test',
pr.Date = '2012-07-31',
from prDetail pd
left join pr on pd.ID = pr.ID
where pd.Code = '45007'
and pr = '2019'
and pr.Item = '1'
This is not working for me (it's showing this error: Incorrect syntax near ','). Can this be achieved in some way?
No.
You can only update one table at a time.
Separate your update into two update queries, and if necessary, wrap them in a transaction.
Yes, As #podiluska said you can only update one table at a time. And you can also use transaction for executing both query with a single transaction.
Else,
If your table/relation has dependency (foreign key and primary key ) relation , then you can use cascade options.
Else,
You can use Trigger.
No, it's not possible to update two at a time but you may consider wrapping it up in a stored procedure and calling that instead. You should try to avoid triggers for something like this if possible.
I have read other posts and I really don't understand what I am doing wrong here because it is such a simple statement.
anything in '()' are comments
Query:
[UPDATE users, sites
SET users.idSiteRegUsers='1'
WHERE sites.SiteActivateSites='DEL' ]
(TBL's to select to update within the whole query)
(Setting the users tbl idSiteRegUsers to 1)
(Where only the sites in tbl sites = DEL)
I've also read http://bugs.mysql.com/bug.php?id=52651 and tried changing the INT to VARCHAR and UPDATING 0 to DEL due to the bug but still same result.
Issue:
I have 2129 records that need updating as found using a simple select statement to understand the number of results.
([SELECT
sites.SiteActivateSites,
sites.id_Sites,
users.idSiteRegUsers,
users.CompanyNameUsers,
sites.LinkNameSites
FROM
users
INNER JOIN sites ON users.idSiteRegUsers = sites.id_Sites
WHERE
sites.SiteActivateSites != '1']) 'simple'
But the UPDATE query updates all 4000+ records, not just the records that = DEL but the ones that are reference to another value e.g. = 1.
Have I missed something?
Cheers,
Joe
Just as with your SELECT command, you need to tell MySQL how the tables are joined: your UPDATE is currently doing a full cartesian product of both tables (with every row in users joined with every row in sites - therefore the WHERE condition filtering on sites is still resulting in a match on every record from users).
Try instead:
UPDATE users JOIN sites ON users.idSiteRegUsers = sites.id_Sites
SET users.idSiteRegUsers='1'
WHERE sites.SiteActivateSites='DEL'
I'm hesitant to run this query which deletes data (for obvious reasons).
I would like to delete the the matching rows from two tables, where the ID = the ID of a third table (which i want to remain unaffected)
This is the exact query I would like to run:
DELETE FROM ItemTracker_dbo.Transaction t,
ItemTracker_dbo.Purchase p
USING ItemTracker_dbo.Transaction
INNER JOIN ItemTracer_dbo.Purchase ON p.Transaction_ID = t.Transaction_ID
INNER JOIN ItemTracker_dbo.Item i ON i.Item_ID = p.Item_ID
WHERE i.Client_ID = 1
To test this, i tried running a select replacing DELETE FROM with SELECT * FROM, and I get a syntax error 'near USING'. When I remove USING ... it selects EVERY row in the table (ignoring the client_id=1 clause).
I (essentially) copied the syntax from the mysql manual (obviously replacing the values).
Is this query valid?
I'm sorry I didn't comment instead of post, but I just don't have enough reputation. Why don't you run it as a transaction and see the results? Or am I missing something?
http://dev.mysql.com/doc/refman/5.0/en/commit.html
As far as I know, you can't do that. The way to acomplish that is with a transaction.
START TRANSACTION;
DELETE FROM tableOne WHERE criteria;
DELETE FROM tableTwo WHERE criteria;
COMMIT;
If something goes wrong between the statements, you can issue a ROLLBACK and your data will be there.
The catch is, THIS WON'T WORK WITH MyISAM. MyISAM doesn't support transactions, so it will simply delete the data and there is no way to roll it back. They need to be InnoDB tables. It does this silently. I've lost a production table that way (good thing I had a backup and it wasn't updated much).
Easiest way to find out if the tables are InnoDB?
SHOW CREATE TABLE tableName;
At the end, it will have something like 'Engine = InnoDB' or 'Engine = MyISAM'.
I'm not familiar with this (non-standard?) use of USING to join tables in the above, but if you just want to delete rows from only some of the tables in the join the normal way would be:
DELETE Purchase, `Transaction`
FROM Item
JOIN Purchase ON Purchase.Item_ID=Item.Item_ID
JOIN `Transaction` ON `Transaction`.Transaction_ID=Purchase.Transaction_ID
WHERE Item.Client_ID=1;
Assuming I understand your schema right. It seems a bit unusual to be deleting the Transaction that is referenced from the Purchase as this would naturally be a many-Purchases-to-one-Transaction relation. Is there a UNIQUE constraint to ensure it is one-to-one? If not, can you be sure no other Purchase will be referencing the deleted Transaction?
You can test the above construct as a SELECT simply:
SELECT Purchase.Purchase_ID, `Transaction`.Transaction_ID
FROM Item ...