An elongated copy query in MS Access - sql

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>

Related

Converting null value to 0 for all fields in MS access

I have a monthly sales table for different customers in ACCESS. The field names are in order Sales_201601, Sales_201602 etc. which changes dynamically with every data refresh.
I am looking for a SQL query which can automatically pick all columns with structure Sales_: and change null value to 0 in ACCESS.
I cannot put the field names individually, because table has many columns and field names changes over time. So need to write a code which changes dynamically with the field names.
I am new to MS access. Please help me.
Thanks
You can update the fields individually:
update t
set Sales_201601 = nz(Sales_201601, 0),
Sales_201602 = nz(Sales_201602, 0)
. . . ;
More importantly, you want to prevent this in the future. The idea is to set the column to not null and set a default value. I think the following works in MS Access:
alter table t alter Sales_201601 not null default 0;
You should do this when new columns are added into the table.
By the way, this would be much simpler if each column were on a separate row.

Sql loop through the values on a table

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!

Access 2010 SQL - UPDATE query not working

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)

update one table using data from another table

I am trying to update my current table by drawing data from another table.
My database (dbo_finance)
column - test
The other database is assestsc and I am going to pull the data from column issuename1,
however I only want to pull the issuename1 when the field [MinSecClass] is = 9.
This is what I wrote
UPDATE dbo_finance
SET [dbo_finance].cusip9 = AssetsC.cusip
FROM dbo_finance INNER JOIN AssetsC ON dbo_finance.test = AssetsC.[IssueName1]
WHERE (AssetsC.MinSecClass = 9)
Thanks, first time really using SQL
Well I would use aliases, it's a good habit to get into:
UPDATE f
SET [dbo_finance].cusip9 = AssetsC.cusip
FROM dbo_finance f
INNER JOIN AssetsC a ON f.test = a.[IssueName1]
WHERE (a.MinSecClass = 9)
Now that will work fine if the assets table will only return one value for cuspid for each record. If this is a one to many relationship you may need to get more complex to truly get the answer you want.
I see several serious design flaws in your table structure. First joins fields that are dependant as something as inherently unstable as issue name are a very poor choice. You want PK and FK field to be unchanging. Use surrogate keys instead and a unique index.
The fact that you have a field called cusp9 indicates to me that you are denormalizing the data. Do you really need to do this? Do you undestand that this update will have to run in a trigger ever time the cuspid assoicated with MinSecClass changes? Whya re you denormalizing? Do you currently have performance problems? A denormalized table like this can be much more difficult to query when you need data from several of these numbered fields. Since you already have the data in the assets table what are you gaining except a maintenance nightmare by duplicating it?
UPDATE dbo_finance
SET cusip9 = (
SELECT A1.cusip
FROM AssetsC AS A1
WHERE dbo_finance.test = A1.IssueName1
AND AssetsC.MinSecClass = 9
)
WHERE EXISTS (
SELECT *
FROM AssetsC AS A1
WHERE dbo_finance.test = A1.IssueName1
AND A1.MinSecClass = 9
);
Because you're using SQL 2008, you can take advantage of the new(ish) MERGE statement.
MERGE INTO dbo_finance
USING (SELECT IssueName1, cusip FROM AssetsC WHERE MinSecClass = 9) AS source
ON dbo_finance.test = source.IssueName1
WHEN MATCHED THEN UPDATE SET dbo_finance.cusip9 = source.cusip;

error with a sql query because of ambiguous column name

I'm trying to create a sql query, but there is this error:
Ambiguous column name 'description'.
Its because this column occurs in both tables.
if I remove the description from the query, it works.
I tried to rename the description-field "AS description_pointer", but the error still occurs.
SELECT TOP 1000 [activityid]
,[activitytypecodename]
,[subject]
,[regardingobjectid]
,[contactid]
,[new_crmid]
,[description] AS description_pointer
FROM [crmtestext_MSCRM].[dbo].[FilteredActivityPointer] as I
Left JOIN [crmtestext_MSCRM].[dbo].[FilteredContact]
ON I.[regardingobjectid] = [crmtestext_MSCRM].[dbo].[FilteredContact].[contactid]
WHERE new_crmid not like '%Null%' AND activitytypecodename like '%E-mail%'
Both tables coming into play in the query have a column named description. You RDBMS cannot guess which column table you actually want.
You need to prefix the column name with the table name (or table alias) to disambiguate it.
Bottom line, it is a good practice to always prefix column names with table names or aliases as soon as several tables come into play in a query. This avoids the issue that you are seeing here and make the queries easier to understand for the poor souls that have no knowledge of the underlying schema.
Here is an updated version of your query with table aliases and column prefixes. Obviously you need to review each column to put the correct alias:
SELECT TOP 1000
i.[activityid]
,i.[activitytypecodename]
,i.[subject]
,c.[regardingobjectid]
,c.[contactid]
,c.[new_crmid]
,c.[description] AS description_pointer
FROM [crmtestext_MSCRM].[dbo].[FilteredActivityPointer] as i
Left JOIN [crmtestext_MSCRM].[dbo].[FilteredContact] as c
ON i.[regardingobjectid] = c.[contactid]
WHERE i.new_crmid not like '%Null%' AND i.activitytypecodename like '%E-mail%'