I need to create a query for updating a column in a table with values taken from another table and matching a field.
These are the 2 tables:
tblMain
ID Autonumbering
Key Text
Stat1 Integer
tblStat1
ID Autonumbering
Key Text
Freq Integer
I want to UPDATE the tblMain.Stat1 column with tblStat1.Freq value on each record in which tblMain.Key = tblStat1.Key.
I tried this syntax (found somewhere as an example)
UPDATE tblMain
SET tblMain.Stat1 = tblStat1.Freq
WHERE tblMain.Key = tblStat1.Key;
This doesn't work and returns an error on the 2nd row.
After some trials I found that the correct syntax (built with the Access query generator) is this:
UPDATE (tblMaibn INNER JOIN tblStat1 ON tblMain.Key = tblStat1.Key)
SET tblMain.Stat1 = tblStat1.Freq;
In this 2nd syntax, there is no trace of the WHERE condition.
Can someone help me to understand what's wrong with the 1st syntax.
Since I'm building a new table (the join), how can it work on tblMain?
As I said, I found the wrong syntax as an example of UPDATE statement.
Thank you in advance.
Bye,
Ivano
What is happening in your first query on the 2nd row, is that Access isn't aware of what tblStat1 represents in your query.
The reason your 2nd query is working is because it uses an inner join on the relevant key. In order for SQL to be aware of what record in tblMain relates to which record in tblStat1, you need to use a join.
You can see in the generated code that it is updating your desired table, but joining onto the second table. The where condition is redundant as you're updating every record.
In 1st syntax, you can change:
UPDATE tblMain
SET tblMain.Stat1 = (SELECT Freq
FROM tblStat1
WHERE tblMain.Key = tblStat1.Key)
Related
first off, noob alert! :))
I need to construct a query that runs on many tables. The tables vary on name just on the last digits as per client code. The thing is, the values that change aren't sequential so looping as in i=1,2,3,... does not work. A possible solution would be to have those values on a given field on an other table.
Here is the code for the first two clients 015 and 061. The leading zero(s) must are essential.
SELECT LnMov2017015.CConta, RsMov2017015.DR, RsMov2017015.NInt, "015" AS CodCli
FROM LnMov2017015 INNER JOIN RsMov2017015 ON LnMov2017015.NReg = RsMov2017015.NReg
WHERE (((LnMov2017015.CConta)="6" And (LnMov2017015.CConta)="7") AND ((RsMov2017015.DR)=9999))
UNION SELECT LnMov2017061.CConta, RsMov2017061.DR, RsMov2017061.NInt, "061" AS CodCli
FROM LnMov2017061 INNER JOIN RsMov2017061 ON LnMov2017061.NReg = RsMov2017061.NReg
WHERE (((LnMov2017061.CConta)="6" And (LnMov2017061.CConta)="7") AND ((RsMov2017061.DR)=9999))
...
So for the first SELECT the table Name is LnMov2017015, the ending 015 being the value, the client code, that changes from table to table e.g. in the second SELECT the table name is LnMov2017061 (061) being what distinguishes the table.
For each client code there are two tables e.g. LnMov2017015 and RsMov2017015 (LnMov2017061 and RsMov2017061 for the second set client shown).
Is there a way that I can build the SQL, based upon the example SQL above?
Does anyone have an idea for a solution? :)
Apparently it is possible to build a query object to read data in another db without establishing table link. Just tested and to my surprise it works. Example:
SELECT * FROM [SoilsAgg] IN "C:\Users\Owner\June\DOT\Lab\Editing\ConstructionData.accdb";
I was already using this structure in VBA to execute DELETE and UPDATE action statements.
Solution found :)
Thank you all for your input.
Instead of linking 100 tables (password protected), I'll access them with SLQ
FROM Table2 IN '' ';database=C:\db\db2.mdb;PWD=mypwd'
And merge them all with a query, before any other thing!
I have a question on SQL execution sequence. I'm using nested iif() conditional statements in MS-Access and because character length became too long, I wanted to use an alias in the statement.
I tried this (by accident) and it works and I'm not sure why and if I should actually use it. Below are shortened examples of the original format compared to the second with enough of the statement to get the gist of it (using generic table names).
I want to update the upDateMe table.
Original pre-alias :
UPDATE upDateMe
INNER JOIN linkMe
ON (linkMe.UniqueID = upDateMe.UniqueID)
AND (linkMe.SrcNumber = upDateMe.SrcNumber)
SET upDateMe.ExpiryDate = [linkMe].[ExpiryDate]
, upDateMe.PermitEnd = [linkMe].[PermitEnd]...
Here I've reversed the tables and put in the alias 'bData':
UPDATE linkMe
INNER JOIN upDateMe AS bData
ON (linkMe.UniqueID = bData.UniqueID)
AND (linkMe.SrcNumber = bData.SrcNumber)
SET bData.ExpiryDate = [linkMe].[ExpiryDate]
, bData.PermitEnd = [linkMe].[PermitEnd]...
This second query works!??. I'm not really sure as to why it would. Can someone explain it??
Because the left side of the set statement is ALWAYS what gets updated.
In code (most maybe not all) you set a variable by setting it = to some value on the right side. The LEFT side is always the target.
In this case, you're telling the database to update the join of linkMe and upDateMe (as bData) setting the bData values to the linkme values. You would likely get an error if you tried to update both bdate and linkMe at the same time as engines generally are only able to update 1 table at a time, since no such conflict seems to exist here, bData is updated without issue.
Working through some insert/update queries on an application today and came across a result I hadn't expected.
Queries
My insert queries look similar to this:
PARAMETERS nm TEXT(10), st TEXT(2);
INSERT INTO park(pname, pstate)
VALUES([nm],[st]);
And their companion updates were like this:
PARAMETERS id LONG, nm TEXT(10), st TEXT(2);
UPDATE park
SET
pname = [nm], pstate = [st]
WHERE
ID = [id];
The table they were updating was similar to this:
park
ID LONG | pname TEXT(10) | pstate TEXT(2)
Unexpected Result
Working through writing the queries, I tested each by running it against the database and providing test values for the various parameters. After the insert query, I'd test the update by updating the newly inserted record.
In most cases the tables were empty, so the update would simply update the single record in place.
However as soon as I ran the update on a previously populated table, I found the query was attempting to update ALL records, not just the one whose ID was being provided through the parameter.
The question is why??
Problem
While ID certainly was a field in the park table, using id as a parameter was essentially stating the following in the WHERE clause:
WHERE ID = id;
or
WHERE ID = ID;
Since ID is always equal to itself, the UPDATE attempted to update ALL records instead of only the expected record with the provided ID.
Solution
To fix the problem, I simply used the first and last letter of the table being updated before the id for each case I was updating a record identified by its ID. So the working code - that updates only the record identified - is:
PARAMETERS pkid LONG, nm TEXT(10), st TEXT(2);
UPDATE park
SET
pname = [nm], pstate = [st]
WHERE
ID = [pkid];
Obviously I wasn't paying close attention while I was writing the query -- while I'd used different names for other parameters, I didn't do so when it came to the ID for the update query.
Bottom Line
Whenever working with paramaterized queries, make sure your parameter names DO NOT match your table's field names.
Doing so will avoid the issue noted above as well as other related issues.
You'll also want to avoid reserved words for your table, field, and parameter names.
Hope this helps someone avoid a possibly nasty surprise when updating records -- or trying to figure out why their parameter queries didn't seem to work.
So, I learnt the joys(/s) of INNER JOIN today. Now I need to copy select records from certain specific columns into my main column. Once again, I'll be using the following format:
Please bear in mind that I'm working with 300,000 records. Copy/pasting one by one is not practical.
Tables:
MainTab
CritTab
Key column:
MainTab:- LINK
CritTab:- FORNLINK
Columns to be copied
CritTab.DATE
CritTab.CODE
Criteria
WHERE CritTab.[CODE] = <This kinda code> OR <This other code>
AND CritTab.[FORNLINK] = MainTab.[LINK]
So, to clarify: I need to copy specific columns from CritTab to MainTab. As not every record in MainTab will have a corresponding CritTab entry, I cannot simply copy and paste the entire column, as some records won't match up.
Is it possible to do this with a query in Access?
I'm not sure if you need the columns added or not, but if you do run these first. I am changing the column name because you should never use keywords as a column, table or variable name.
ALTER TABLE MainTab ADD COLUMN DATENAME DATETIME
ALTER TABLE MainTab ADD COLUMN CODENAME (WHATEVER DATA TYPE IT IS IN CritTab)
I am moving the JOIN operator from the where clause to the FROM clause. This usually makes it easier to understand how the data is being built and clutters the WHERE a bit less in my opinion. Note: I am doing the same sort of syntax as the article Mike posted in the comments.
UPDATE MainTab INNER JOIN CritTab ON CritTab.[FORNLINK] = MainTab.[LINK]
SET MainTab.DATENAME = CritTab.[Date], MainTab.CODENAME = CritTab.[CODE]
WHERE CritTab.[CODE] = <This kinda code> OR CritTab.[CODE] = <This other code>
I have created a lookup table in Access to provide the possible values for a column. Now I need to update this column with the data it had before I converted the column. I am unable to figure out a SQL Query that will work. I keep getting the error "An UPDATE or DELETE query cannot contain a multi-valued field." My research has suggested that I just need to set the value of the column but this always updates 0 records:
UPDATE [table_name] SET [column_name].Value = 55 WHERE [table_name].ID = 16;
I know this query will work if I change it to update a text column, so it is definitely a problem with just this column.
If you're adding a value to your multi-valued field, use an append query.
INSERT INTO table_name( [column_name].Value )
VALUES (55)
WHERE ID = 16;
If you want to change one particular value which exists in your multi-valued field, use an UPDATE statement. For example, to change the 55 to 56 ...
UPDATE [table_name]
SET [column_name].Value = 56
WHERE [column_name].Value = 55 And ID = 16;
See Using multivalued fields in queries for more information.
I have figured this out! It certainly was counter-intuitive! You have to use an INSERT statement to do the update.
-- Update a record with a multi-valued field that has no value
INSERT INTO [table_name] ( [[column_name].[Value] )
VALUES(55)
WHERE [table_name].ID = 16;
This confused me because I was expecting an UPDATE statement. I think it actually inserts a record into a hidden table that is used to associate multiple values with this column.
I am working with Sharepoint, I created the tables as multi-value fields, ran into the error with my INSERT INTO statement, went back to Sharepoint to change to non-multi-value fields, but that didn't fix it.
Recreated the table without using multi-value fields, and the INSERT INTO worked just fine.
do not use the .value part
UPDATE [table_name] SET [column_name] = 55 WHERE [table_name].ID = 16;
INSERT INTO Quals (cTypes.[value])
SELECT Quals_ContractTypes.ContractType
FROM Quals_ContractTypes
WHERE (Quals.ID = Quals_ContractTypes.ID_Quals);
I gotta say I didn't understand very well your problem but I saw something strange in your query. Try this:
UPDATE [table_name] SET [column_name]= 55 WHERE [table_name].ID = 16;
UPDATE:
Look at this link: it has an example
UPDATE Issues
SET Issues.AssignedTo.Value = 10
WHERE (((Issues.AssignedTo.Value)=6)
AND ((Issues.ID)=8));
NOTES
You should always include a WHERE
clause that identifies only the
records that you want to update.
Otherwise, you will update records
that you did not intend to change. An
Update query that does not contain a
WHERE clause changes every row in the
table. You can specify one value to
change.
The Multi-Valued field refers to Access databases that have tables with columns, that allow you to select multiple values, like a Combo Checkbox list.
THOSE are the only Access types that SQL cannot work with. I've tested all Access lookup possibilities, including hard-coded values, and lookup tables. They work fine, but if you have a column that has the Allow Multiple select options, you're out of luck. Even using the INSERT INTO as mentioned below, will not work as you'll get a similar but different error, about INSERTing into multi-valued fields.
As mentioned it's best to avoid using such tables outside of Access, and refer to a table specifically for your external needs. Then write a macro/vba script to update the real tables with the data from the "auxiliary" table.