Access Update Query Shows Records being updated but doesn't update some - ms-access

Simple update query that has been working for weeks but now seems to update only some of the records.
Both tables have ID's that I use to match between them, I clearly see that the records that need to be updated are there when I look at the query results but when I run the query and look at the table being updated there are some fields not populated. Very strange since they are showing up when I look into the query but then only some are updated in the table.
Here's the query;
UPDATE [Asset List]
INNER JOIN [Combine Control] ON [Asset List].ID = [Combine Control].ID
SET [Asset List].[Completed 2022] = [Combine Control].[Completed];
Anything I'm overlooking or if anyone has had this issue before please let me know. Thank you.

Related

Improve delete with IN performance

I struggle to write a DELETE query in MariaDB 5.5.44 database.
The first of the two following code samples works great, but I need to add a WHERE statement there. That is displayed in the second code sample.
I need to delete only rows from polozkyTransakci where puvodFaktury <> FAKTURA VO CZ in transakce_tmp table. I thought that my WHERE statement in the second sample could have worked ok with the inner SELECT, but it takes forever to process (it takes about 40 minutes in my cloud based ETL tool) and even then it does not leave the rows I want untouched.
1.
DELETE FROM polozkyTransakci
WHERE typPolozky = 'odpocetZalohy';
2.
DELETE FROM polozkyTransakci
WHERE typPolozky = 'odpocetZalohy'
AND idTransakce NOT IN (
SELECT idTransakce
FROM transakce_tmp
WHERE puvodFaktury = 'FAKTURA VO CZ');
Thaks a million for any help
David
IN is very bad on performance .. Try using NOT EXISTS()
DELETE FROM polozkyTransakci
WHERE typPolozky = 'odpocetZalohy'
AND NOT EXISTS (SELECT 1
FROM transakce_tmp r
WHERE r.puvodFaktury = 'FAKTURA VO CZ'
AND r.idTransakce = polozkyTransakci.idTransakce );
Before you can performance tune, you need to figure out why it is not deleting the correct rows.
So first start with doing selects until you get the right rows identified. Build your select a bit at time checking the results at each stage to see if you are getting the results you want.
Once you have the select then you can convert to a delete. When testing the delete do it is a transaction and run some test of the data that is left behind to ensure it deleted properly before rolling back or committing. Since you likely want to performance tune, I would suggest rolling back, so that you can then try again on the performance tuned version to ensure you got the same results. Of course, you only want to do this on a dev server!
Now while I agree that not exists may be faster, some of the other things you want to look at are:
do you have cascade deletes happening? If you end up deleting many
child records, that could be part of the problem.
Are there triggers affecting the delete? especially look to see if someone set one up to run through things row by row instead of as a set. Row by row triggers are a very bad thing when you delete many records. For instance suppose you are deleting 50K records and you have a delete trigger to an audit table. If it inserts to that table one record at a time, it is being executed 50K times. If it inserts all the deleted records in one step, that insert individually might take a bit longer but the total execution is much shorter.
What indexing do you have and is it helping the delete out?
You will want to examine the explain plan for each of your queries to
see if they are improving the details of how the query will be
performed.
Performance tuning is a complex thing and it is best to get read up on it in detail by reading some of the performance tuning books available for your specific database.
I might be inclined to write the query as a LEFT JOIN, although I'm guessing this would have the same performance plan as NOT EXISTS:
DELETE pt
FROM polozkyTransakci pt LEFT JOIN
transakce_tmp tt
ON pt.idTransakce = tt.idTransakce AND
tt.puvodFaktury = 'FAKTURA VO CZ'
WHERE pt.typPolozky = 'odpocetZalohy' AND tt.idTransakce IS NULL;
I would recommend indexes, if you don't have them: polozkyTransakci(typPolozky, idTransakce) and transakce_tmp(idTransakce, puvodFaktury). These would work on the NOT EXISTS version as well.
You can test the performance of these queries using SELECT:
SELECT pt.*
FROM polozkyTransakci pt LEFT JOIN
transakce_tmp tt
ON pt.idTransakce = tt.idTransakce AND
tt.puvodFaktury = 'FAKTURA VO CZ'
WHERE pt.typPolozky = 'odpocetZalohy' AND tt.idTransakce IS NULL;
The DELETE should be slower (due to the cost of logging transactions), but the performance should be comparable.

Read-only after inner join (MySQL)

In MySQL workbench (Mac OS), I wanted to join two tables so that I can update the second one. The code I put in was as follows
select f.company, f.remarks, c.pic
from feedback f, customers c
where f.col = c.col
order by f.company;
The output is a read only table, which prevented me from updating table "customers" based on the f.remarks column.
Your advice/suggestion is appreciated. Thank you.
By hovering above the "Read Only" icon, I got the following message:
"Statement must be a SELECT from a single table with a primary key for its results to be editable".
After some research based on the advice given by fellow coders, here are some points to note:
In MySQL workbench, one cannot edit the results obtained from any JOINs because it's not from a single table;
In using SELECT from a single table, the primary key must be included in order for the result to be editable.
Thank you to everyone who contributed to the question. I appreciate it.
The problem is because, as you mentioned, SELECT only returns a "read only" result set.
So basically you cant use MySQL workbench to update a field in a read only result set that is returned when using a JOIN statement.
from what i understand you want to update table "customers" based on a query.
maybe this post will help you:
update table based on subquery of table

Set two values in one table based on sum of a column in another table

I have two tables, a "data" table with hundreds of thousands of rows, and a "settings" table with hundreds of rows. I need to update two values in the settings table, based on the sum of one column in the data table being greater than another column in the settings table, where the 'id' of the settings table matches the 'offerid' of the data table.
I've been cruising Google looking at many possible solutions, but I don't seem able to bend any of them to my needs. Any time I start working with Joins, I inevitably get tripped up.
My latest attempt which did not work, is:
UPDATE settings a, data b
SET a.hidden=1, a.weight=0
WHERE a.id = b.offerid
AND sum(b.views) > a.target
I liked this flavor of approach as I thought it actually made sense to me, but all I get is "Error code 1111: Invalid us of group function". Maybe someone here can point me in the right direction.
It errors out because you are using an aggregate function (sum) with no grouping. So query really does not know which rows should be summed together. You can use a subquery like this:
UPDATE settings a
INNER JOIN
(
SELECT
sum(b.views) sumviews, b.offerid
from data b
group by b.offerid
) c on c.offerid = a.id
SET a.hidden=1, a.weight=0
where c.sumviews>a.target
EDIT: To disable the safe update function do the following steps
Follow the steps below before executing the UPDATE command:
Go to Edit --> Preferences
Click "SQL Queries" tab and uncheck "Safe Updates" check box
Query --> Reconnect to Server
Now execute your sql query
Source: Disable Safe Update
Try using
HAVING
instead of
AND
So your code goes like:
UPDATE settings a, data b
SET a.hidden=1, a.weight=0
WHERE a.id = b.offerid
GROUP BY a.id
HAVING sum(b.views) > a.target

Mysql UPDATE before first checking if necessary or just UPDATE?

I'm using mysql to update a field in a table when a condition is met...
Should I first do a SELECT to see if the condition is met or do I just try to use UPDATE every time, because if the condition is not met, nothing happens.
To be concrete, here is my SELECT:
SELECT * FROM forum_subscriptions
WHERE IDTopic=11111 AND IDUser=11111 and status=0
I am checking here if I am on forum topic 11111 and if if I (user ID 1) is subscribed to this topic and my status on the subscription is 0 (that means that he didn't yet get email about new post in topic)
So when this is met do:
UPDATE forum_subscriptions SET Status=1 where IDTopic=11111 AND IDUser=1
Now I am wondering, I always do a select here to query if a user is subscribed to this topic and he has a status that he visited that topic before so any new posts will not trigger new email notification. When he visits the page again, the update is triggered that resets the visit so any new posts will again send him email.
So select is made on every user if he is subscribed or not to test the subscription. Update is made only when necessary.
Is it better to just use the update? To try to update on every page, if he is not subscribed to the topic it will not update anything.
How fast is update that doesn't produce any valid data? How is it made internally, how does update find if there is any record, does it select and then update? If so it would be better to only update because I would achieve same thing without any slowdowns. If the update is more expensive than select I should try to check first and then update if necessary.
This example is a real life example, but the logic behing this update/select is really what I am interested because I do find this kind of a problem more often.
Thanx
UPDATE: Thanx both guys, but I do not see on your links if UPDATE is locking even without results or not. As you gave different answers I still don't know what to do.
The subscription table really doesn't need to be myisam, I could change it to InnoDB because I don't have a need to fulltext it. Is this a good solution, to only use update and change this small table to inno? Does mixing table types have any drawbacks?
You just do the update, with no previous select:
UPDATE forum_subscriptions SET Status=1 where IDTopic=11111 AND IDUser=1
If the conditions are not met, update will do nothing.
This update is very fast if you have an index on status and IDtopic and IDuser!
An empty update is just as fast as an empty select.
If you do the select first, you will just slow things down for no reason.
If you want to know how many rows where updated do a
SELECT ROW_COUNT() as rows_affected
After doing the update, this will tell you 0 if no rows where updated, or the number of rows updated (or inserted or deleted, if you used those statements).
This function is ultra fast because it just has to fetch one value from memory.
Workarounds for table locking issues
See here: http://dev.mysql.com/doc/refman/5.5/en/table-locking.html
A potential side affect of always calling the UPDATE is the locking that needs to be put to insure that no other connection modifies these rows.
If the table is MyISAM - a lock will be places on the he entire table during the search.
If the table is InnoDB, locks will be places on the indexes/gaps.
From the Docs:
A locking read, an UPDATE, or a DELETE
generally set record locks on every
index record that is scanned in the
processing of the SQL statement. It
does not matter whether there are
WHERE conditions in the statement that
would exclude the row

mysql update math

say p.products_price equals 1
why does:
UPDATE products p
SET p.products_price = (1 + p.products_price)
WHERE p.products_id = 8
make p.products_price equals 3?
It is adding 1 to the price and then doing it all over again? I am trying to do something a little more complicated but when it didn't work I broke it down to the simplest thing ever. Can I make some kind of temporary value here and calculate the new price and then set it to that?
Please help I am raging,
Thanks.
MySQL client version: 4.1.22
edit: the column is decimal type, i tried the same update on an int column with the same result.
edit: this is not running in code so there is no chance of the code calling the same update twice
UPDATE products
SET products_price = (1 + products_price)
WHERE products_id = 8
works like it should (removed table alias 'p')
Your SQL looks fine. Is the 'something' column unique? Make sure that you are only updating a single record.
That should definitely set products_price to 2. There must be something else going on.
This is similar to Problem with updating a MySQL field with PHP but there was no good solution there so I'll leave this one open too.
Are you running it from the client, or through a script?
Do you have any transactions open or other scripts accessing the database?
Edit: You mentioned joins in your comment - I'd be willing to bet that your join is pulling back the same row more than once.