Home » excel » vba – Construct the correct SQL String for ADO to get data with MAX Date

vba – Construct the correct SQL String for ADO to get data with MAX Date

Posted by: admin April 23, 2020 Leave a comment

Questions:

I am retrieving data from a closed Excel Binary file using ADO.
I have 2 Sheets in that file and what I want is to retrieve all data from Sheet1 where ID exist in Sheet2.
And I was able to do just that by:

sqlstr = "SELECT e.NOTES, u.SPO, e.ID, e.REF, e.PID "
sqlstr = sqlstr & ", e.DESCRIPTION, e.CreateDate "
sqlstr = sqlstr & "FROM [Sheet2$] u "
sqlstr = sqlstr & "INNER JOIN [Sheet1$] e "
sqlstr = sqlstr & "ON e.ID = u.ID;"

The problem arise when a specific ID was reflected 2 or more x in Sheet1 but with different dates.
I need to retrieve ID with the highest Data only and so I try below:

sqlstr = "SELECT e.NOTES, u.SPO, e.ID, e.REF, e.PID  "
sqlstr = sqlstr & ", e.DESCRIPTION, e.CreateDate "
sqlstr = sqlstr & "FROM [Sheet2$] u "
sqlstr = sqlstr & "INNER JOIN (SELECT ID, REF, PID, DESCRIPTION, NOTES, MAX(CreateDate) "
sqlstr = sqlstr & "FROM [Sheet1$] GROUP BY ID, REF, PID, DESCRIPTION, NOTES) e "
sqlstr = sqlstr & "ON e.ID = u.ID;"

Unfortunately, this doesn’t work and gives me this error:

enter image description here

I tried isolating my Sub Query like this:

sqlstr = "SELECT ID, REF, PID, DESCRIPTION, NOTES, MAX(CreateDate) "
sqlstr = sqlstr & "FROM [Sheet1$] GROUP BY ID, REF, PID, DESCRIPTION, NOTES;"

It works fine. It returns all ID with the maximum date only.
My questions are:

  1. Why doesn’t it work when I try to use it as Sub Query.
  2. Does ADO support Sub Query when pulling data from Excel files or databases?
  3. Is there a way to get the result I wanted using just a query?

Any help is appreciated.

Clarification: The Sub Query works if I run it using SQL. I was trying to make it work using ADO. This is the first time I’m doing a Sub Query in an SQL String for use in opening a record set. So I thought maybe I’m doing something wrong or doing something out of the scope.

How to&Answers:

You might be overdoing things.

Try this:

(untested code)

SELECT e.NOTES, u.SPO, e.ID, e.REF, e.PID, e.DESCRIPTION, MAX(e.CreateDate) as CreateDate 
FROM [Sheet1$] e  
INNER JOIN [Sheet2$] u ON e.ID = u.ID 
GROUP BY e.ID, e.REF, e.PID, e.DESCRIPTION, e.NOTES, u.SPO

Answer:

I would first join Sheet1 to Sheet2 followed by joining a subquery which will only have the max created dates. Something like this:

SELECT e.NOTES, u.SPO, e.ID, e.REF, e.PID, e.DESCRIPTION, e.CreateDate
FROM [Sheet2$] u

INNER JOIN [Sheet1$] e
ON e.ID = u.ID

INNER JOIN (
    SELECT ID, MAX(CreateDate) AS MaxCD
    FROM [Sheet1$]
    GROUP BY ID
) AS MCD
ON e.ID = MCD.ID
AND e.CreateDate = MCD.MaxCD

What this is essentially doing is:

  • Joining all results from Sheet1
  • Joining Sheet1 again but only with the highest created date.