Insert Into SQL VBA - sql

I am trying to select records that are in the first table but not in the second table and insert them into the second table using a sql statement in VBA. I have started it below but I am not sure why it won't work. I am rather new to sql so any help would be greatly appreciated.
MySQL = "INSERT INTO Clients ()" & _
"SELECT DISTINCT DD.[Client ID] " & _
"FROM " & tableName & " as DD " & _
"Where DD.[Client ID] NOT IN (SELECT DD.[Client ID] FROM " & tableName & " as DD)"

First, you need supply field list to insert statement:
INSERT INTO Clients (ClientID)...
Second, your query doesn't insert any rows, because you check ClientID presence in same table. Did you mean someting like next:
"Where DD.[Client ID] NOT IN (SELECT DD2.[Client ID] FROM " & tableName2 & " as DD2)"

Related

SQL VBA Group by error with TRUNC() function

im doing a query on vba excel, i ave a problem with this query:
SQLStr = "SELECT DISTINCT (t2.COD_CF) AS CODICE_CLIENTE, (t2.RAG_SOC_CF) AS CLIENTE, (t1.DES_HEAD_DOC) AS COMMESSA_E_DESCRIZIONE, t1.DATA_PREV_FIN_LAV AS GREZZO_CONFERMATO, MIN(t4.DATA_INIZIO) AS PRIMO_CARICO, MAX(t4.DATA_FINE) AS ULTIMO_CARICO, " & _
"(TRUNC(MAX(t1.DATA_PREV_FIN_LAV)) - TRUNC(t4.DATA_INIZIO) ) - " & _
"((((TRUNC(MAX(t1.DATA_PREV_FIN_LAV),'D'))-(TRUNC(t4.DATA_INIZIO,'D')))/7)*2) - " & _
"(CASE WHEN TO_CHAR(t4.DATA_INIZIO,'DY','nls_date_language=english')='SUN' THEN 1 ELSE 0 END) - " & _
"(CASE WHEN TO_CHAR(MAX(t1.DATA_PREV_FIN_LAV),'DY','nls_date_language=english')='SAT' THEN 1 ELSE 0 END) as GG_DIFFERENZA " & _
"FROM COMM_LAV t1 " & _
"INNER JOIN CF t2 ON t1.COD_CF_INTE = t2.COD_CF " & _
"INNER JOIN COMM_LAV_LNK t3 ON t1.DOC_ID = t3.DOC_ID " & _
"INNER JOIN ORP_EFF_CICLI_ESEC t4 ON t3.LNK_DOC_ID = t4.DOC_ID " & _
"WHERE t1.DATA_PREV_FIN_LAV >= '" & startDate & "' AND t1.DATA_PREV_FIN_LAV <= '" & endDate & "' AND t4.COD_CICLO <> 'LEV01' " & _
"GROUP BY t2.COD_CF, t2.RAG_SOC_CF, t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV " & _
"ORDER BY t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV, MIN(t4.DATA_INIZIO) "
I get this error: ORA-00979: not a GROUP BY expression
this error there is only when i do the TRUNC() function, someone can help me and explain this group by
UPDATE
I tryed to use oracle and i hav e edit the query like this:
SELECT (t2.COD_CF) AS CODICE_CLIENTE, (t2.RAG_SOC_CF) AS CLIENTE, (t1.DES_HEAD_DOC) AS COMMESSA_E_DESCRIZIONE, t1.DATA_PREV_FIN_LAV AS GREZZO_CONFERMATO, MIN(t4.DATA_INIZIO) AS PRIMO_CARICO, MAX(t4.DATA_FINE) AS ULTIMO_CARICO,
(TRUNC(MAX(t1.DATA_PREV_FIN_LAV)) - TRUNC(t4.DATA_INIZIO)) AS DIFF
FROM COMM_LAV t1
INNER JOIN CF t2 ON t1.COD_CF_INTE = t2.COD_CF
INNER JOIN COMM_LAV_LNK t3 ON t1.DOC_ID = t3.DOC_ID
INNER JOIN ORP_EFF_CICLI_ESEC t4 ON t3.LNK_DOC_ID = t4.DOC_ID
WHERE t1.DATA_PREV_FIN_LAV >= '01-OCT-20' AND t1.DATA_PREV_FIN_LAV <= '30-OCT-20' AND t4.COD_CICLO <> 'LEV01'
GROUP BY t2.COD_CF, t2.RAG_SOC_CF, t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV
ORDER BY t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV, MIN(t4.DATA_INIZIO)
but i have always this error: ORA-00979: not a GROUP BY expression
Why the trunc function give me this error?
The GROUP BY clause needs to include all the fields in your SELECT that are not being GROUPED. You have omitted this one:
(TRUNC(MAX(t1.DATA_PREV_FIN_LAV)) - TRUNC(t4.DATA_INIZIO)) AS DIFF
Even though you have an aggregation function in there (MAX), overall this is a TRUNC statement and so is not an aggregation.
I think logically the following 2 statements are the same (at least as long as B < A):
MAX(A) - B == MAX(A-B)
therefore you should be able to re-write your statement as the following and still get the same result:
MAX(TRUNC(t1.DATA_PREV_FIN_LAV) - TRUNC(t4.DATA_INIZIO)) AS DIFF
You are missing the column TRUNC(t4.DATA_INIZIO) in the GROUP BY:
SELECT t2.COD_CF AS CODICE_CLIENTE, t2.RAG_SOC_CF AS CLIENTE,
t1.DES_HEAD_DOC AS COMMESSA_E_DESCRIZIONE,
t1.DATA_PREV_FIN_LAV AS GREZZO_CONFERMATO,
MIN(t4.DATA_INIZIO) AS PRIMO_CARICO,
MAX(t4.DATA_FINE) AS ULTIMO_CARICO,
(TRUNC(MAX(t1.DATA_PREV_FIN_LAV)) -
TRUNC(t4.DATA_INIZIO)
--------^ Not in GROUP BY
) AS DIFF
FROM COMM_LAV t1 JOIN
CF t2
ON t1.COD_CF_INTE = t2.COD_CF JOIN
COMM_LAV_LNK t3
ON t1.DOC_ID = t3.DOC_ID JOIN
ORP_EFF_CICLI_ESEC t4
ON t3.LNK_DOC_ID = t4.DOC_ID JOIN
WHERE t1.DATA_PREV_FIN_LAV >= DATE '2020-10-01' AND
t1.DATA_PREV_FIN_LAV <= DATE '2020-10-30' AND
t4.COD_CICLO <> 'LEV01'
GROUP BY t2.COD_CF, t2.RAG_SOC_CF, t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV,
TRUNC(t4.DATA_INIZIO)
---------^ add to GROUP BY
ORDER BY t1.DES_HEAD_DOC, t1.DATA_PREV_FIN_LAV, MIN(t4.DATA_INIZIO);
Note that Oracle supports date literals using the DATE keyword. I strongly recommend that you use that.

How to select records from five tables with conditions and read the records to datagridview

I've created an Access database of 5 tables (personalData, WorkExperience, EducationalData, SpouseData, DependantData)
I have STHN_ID as primary key in the first table and as foreign key in the others. I also have a column named DateEngaged as Date/Time.
I try to select from PersonalData where STHN_ID=00001 and DateEngaged is within a Certain date range and it works fine. this is my code is
Dim rcmd As OleDbCommand = New OleDbCommand("Select STHN_ID FROM PersonalData WHERE ([STHN_ID]='" & STHN_ID.Text & "') and ([DateEngaged]>=CDate('" & FromDate.Value & "') AND [DateEngaged] <=CDate('" & ToDate.Value & "'))", myConnection)
My problem is after reading from PersonalData with those conditions and a record is found, it should go ahead and select all the fields in the other tables with that STHN_ID, that is, it should combine all columns in all the tables. the last thing I want to do is to read the combined columns to a datagridview.
So in the datagridview, I have all the columns from PersonalData, WorkExperience, EducationalData, SpouseData and Dependant data. so a row in the datagridview will contain all the records of that particular from the first table to the last table.
This is what I tried but it gives an error
da = New OleDbDataAdapter("Select * FROM [PersonalData] WHERE [STHN_ID]='" & STHNID.Text & "' AND ([DateEngaged]>=CDate('" & FromDate.Value & "') AND [DateEngaged]<=CDate('" & ToDate.Value & "' JOIN select * from EducationalData where STHN_ID='" & STHNID.Text & "' JOIN select * from WorkExperience where STHN_ID='" & STHNID.Text & "' JOIN select * from SpouseData where STHN_ID='" & STHNID.Text & "' JOIN select * from DependantData where STHN_ID='" & STHNID.Text & "'))", myConnection)
Use this query inside dataAdapter:
select PD.STHN_ID
, PD.NAME
, PD.DateEngaged
, ED.NAMEOFSCHOOL
, WE.EMPLOYER
, SD.SPOUSENAME
, DD.DEPENDANTNAME
from PersonalData PD
inner join EducationalData ED on PD.STHN_ID=ED.STHN_ID
inner join SPOUSEDATA SD on PD.STHN_ID=SD.STHN_ID
inner join DEPENDANTDATA DD on PD.STHN_ID=DD.STHN_ID
inner join WORKEXPERIENCE WE on PD.STHN_ID=WE.STHN_ID
WHERE ([PD.STHN_ID]='" & STHN_ID.Text & "')
and ([PD.DateEngaged]>=CDate('" & FromDate.Value & "')
and [PD.DateEngaged] <=CDate('" & ToDate.Value & "'))

Multiple select statements in access vba

I am trying to insert 2 count numbers into a table as one record in access through vba and for some reason it is saying the number of query values and destination fields are not the same when I try to run it. I am very confused why this is happening. Any help would be greatly appreciated
TotalVerified = " INSERT INTO Totals([TOTAL VERIFIED FORMULARIES], [TOTAL AVAILABLE FOR IMPORT]) " & _
"SELECT COUNT([FORMULARY ID]) " & _
"FROM VerifiedFormularies " & _
"AND COUNT([FORMULARY ID])" & _
"FROM ImportMetricsIDs"
I think the query you want is:
INSERT INTO Totals([TOTAL VERIFIED FORMULARIES], [TOTAL AVAILABLE FOR IMPORT])
SELECT CNT1, CNT2
FROM (SELECT COUNT([FORMULARY ID]) as CNT1 FROM VerifiedFormularies) as c1 CROSS JOIN
(SELECT COUNT([FORMULARY ID]) as CNT2 FROMImportMetricsIDs) as c2;
AND is a boolean operator, typically used in a WHERE clause, ON clause, or in an iif() expression. It doesn't connect the values from two subqueries.

Insert Into SQL Statement error 3346

I am trying to INSERT INTO a table in SQL but for some reason it says the number of query values and destination fields are not the same and I'm not sure why it is saying that. I have researched the error (3346) with no luck for a fix. I am rather new to VBA so any help would be greatly appreciated.
"INSERT INTO Clients (Col1, Col2, Col3)" & _
"SELECT DISTINCT DD.[Client ID] " & _
"FROM " & tableName & " as DD " & _
"Where CL.[Client ID] NOT IN (SELECT DD.[Client ID] FROM " & tableName & " as DD)"
You are trying to insert into 3 columns from one column it's confused
this will work:
"INSERT INTO Clients (Col1)" & _
"SELECT DISTINCT DD.[Client ID] " & _
"FROM " & tableName & " as DD " & _
"Where DD.[Client ID] NOT IN (SELECT DD.[Client ID] FROM " & tableName & " as DD)"
but it does not insert any row because there is no result for select statement.
Think a little more on it and decide exactly what do you want to insert into where?

Update record if matching values in same table

I have a MS Access database with a list of transactions. I am trying to update a "Match" field on both records where they have some of the same values in fields (Document Number, Voucher Number, Subhead) but opposite amounts. It also needs to avoid duplicates.
Document Number Amount ABS Match
N6809561990112 438.48 438.48
N6809561990112 438.48 438.48
N6809561990112 -438.48 438.48
What I the end result after the SQL should look like
Document Number Amount ABS Match
N6809561990112 438.48 438.48 Y
N6809561990112 438.48 438.48
N6809561990112 -438.48 438.48 Y
The table name is "tblUnmatched"
I tried the following but it updated every record in the table to "Y"
strSql = "Update tblUnmatched SET match = 'Y' WHERE EXISTS(select * " & _
"from tblUnmatched t1 " & _
"inner join tblUnmatched t2 on " & _
"t1.[DOCUMENT NUMBER] = t2.[DOCUMENT NUMBER]" & _
"where t1.ABS = t2.ABS AND t1.AMOUNT <> t2.AMOUNT AND t1.SUBH = t2.SUBH)"
DoCmd.RunSQL strSql
I also tried this but it couldn't handle the duplicate problem.
strSql = "Update tblUnmatched SET match = 'Y' WHERE [DOCUMENT NUMBER] IN(select t1.[DOCUMENT NUMBER] " & _
"from tblUnmatched t1 " & _
"inner join tblUnmatched t2 on " & _
"t1.[DOCUMENT NUMBER] = t2.[DOCUMENT NUMBER]" & _
"where t1.ABS = t2.ABS AND t1.AMOUNT <> t2.AMOUNT AND t1.SUBH = t2.SUBH)"
DoCmd.RunSQL strSql
Your task is impractical in Access SQL without a primary key field. Although there is no such key in the data source you import, that does not prohibit you from adding one in Access.
Add an autonumber primary key, id, to tblUnmatched. Then for each new batch of incoming data:
import into a scratch table, tblScratch
DELETE FROM tblUnmatched
append the rows from tblScratch into tblUnmatched
(The process could be cleaner if you can use SELECT FROM <your data source> to append directly to tblUnmatched, instead of first importing to tblScratch.)
Save the following SELECT statement as qryFindMatches:
SELECT
sub.[Document Number],
sub.Amount,
sub.MinOfid,
DCount(
"*",
"tblUnmatched",
"[Document Number]='" & [Document Number]
& "' AND Amount = -1 * " & [Amount]
) AS match_count
FROM
(
SELECT [Document Number], Amount, Min(id) AS MinOfid
FROM tblUnmatched
GROUP BY [Document Number], Amount
) AS sub;
Then the UPDATE you want can be fairly easy to create. Beware the performance may not be blazing fast; hopefully you can accommodate it once a month.
UPDATE tblUnmatched
SET [Match] = True
WHERE id In
(
SELECT MinOfId
FROM qryFindMatches
WHERE match_count > 0
);
I added an additional row to your sample data and tested with Access 2007. I think this is what you want ...
id Document Number Amount Match
1 N6809561990112 $438.48 True
2 N6809561990112 $438.48 False
3 N6809561990112 ($438.48) True
4 N6809561990112 $5.00 False