I've managed to get my code to work, but it takes a very long time to execute. I use a series of open and close recordset statements to get the addr_ImportID I'm looking for before executing a final SQL statement and writing the row to a table.
Is there a better way to do what I'm trying to achieve using a better subquery, case statements, if condition or otherwise? My usage of subqueries is slowing things down, so maybe manipulating the data without opening and closing recordsets would be more efficient. Or a better series of select statements?
Here's a sample of what the table looks like:
CnBio_ID | Addr_Type | Addr_ImportID | CnAdrAll_1_IDKEY | CnAdrAll_1_DateLastChanged
0001009 | Previous | 12344 | 1 | 03/15/2014
0001009 | Home | H2345 | 3 | 01/02/2017
0001009 | Home | A2344 | 2 | 01/02/2017
1223144 | Previous | 23441 | 7 | 05/23/2010
1223144 | Other | 31333 | 6 | 08/21/2016
1223144 | Previous | 45848 | 5 | 08/21/2016
The snippet below is one section of my code.
strSql2 = "SELECT Addr_ImportID From [Non-Preferred Home Addresses] WHERE CnBio_ID = '" & rs(0) & "' " & _
"AND CnAdrAll_1_DateLastChanged IN (SELECT Max(CnAdrAll_1_DateLastChanged) FROM [Non-Preferred Home Addresses] " & _
"Where CnBio_ID = '" & rs(0) & "' AND Addr_ImportID IN (SELECT Addr_ImportID From [Non-Preferred Home Addresses] " & _
"WHERE CnBio_ID = '" & rs(0) & "' AND Addr_Type = 'Home'));"
Set rsMaxAddressImportID = DBEngine(0)(0).OpenRecordset(strSql2, dbOpenDynaset)
If Not (rsMaxAddressImportID.EOF) Then
'Condition where more than one Home address exists updated on the same date
If (rsMaxAddressImportID.RecordCount > 1) Then
rsMaxAddressImportID.Close
strSql2 = "SELECT Addr_ImportID FROM [Non-Preferred Home Addresses] WHERE CnAdrAll_1_IDKEY = " & _
"(SELECT Max(CnAdrAll_1_IDKEY) FROM [Non-Preferred Home Addresses] WHERE CnBio_ID = '" & rs(0) & "' AND Addr_Type = 'Home');"
Set rsMaxAddressImportID = DBEngine(0)(0).OpenRecordset(strSql2, dbOpenDynaset)
MsgBox "Row = " & i
End If
- For Each CnBio_ID
- If Home address exists, select Addr_ImportID of row with Max DateLastChanged
- If multiple Home addresses last updated on the same date, select Addr_ImportID of row with Max CnAdrAll_1_IDKEY
- If no Home address, select Addr_ImportID of row with Max DateLastChanged
- If multiple addresses last updated on the same date, select Addr_ImportID of row with max CnAdrAll_1_IDKEY
Updated after question by Parfait
'Select Distinct CIDs to loop through
'strSql = "SELECT CnBio_ID FROM [Non-Preferred Home Addresses] WHERE CnBio_ID = '" & ConstID & "'Group By CnBio_ID;"
strSql = "SELECT CnBio_ID FROM [Non-Preferred Home Addresses] Group By CnBio_ID;"
Set rs = DBEngine(0)(0).OpenRecordset(strSql, dbOpenDynaset)
If Not (rs.EOF And rs.BOF) Then
'MsgBox rs.RecordCount
'This section will loop through all distinct CIDs.
i = 1
Do Until rs.EOF
'Select Non-Preferred Home Address with latest date updated
strSql2 = "SELECT Addr_ImportID From [Non-Preferred Home Addresses] WHERE CnBio_ID = '" & rs(0) & "' " & _
"AND CnAdrAll_1_DateLastChanged IN (SELECT Max(CnAdrAll_1_DateLastChanged) FROM [Non-Preferred Home Addresses] " & _
"Where CnBio_ID = '" & rs(0) & "' AND Addr_ImportID IN (SELECT Addr_ImportID From [Non-Preferred Home Addresses] " & _
"WHERE CnBio_ID = '" & rs(0) & "' AND Addr_Type = 'Home'));"
Set rsMaxAddressImportID = DBEngine(0)(0).OpenRecordset(strSql2, dbOpenDynaset)
If Not (rsMaxAddressImportID.EOF) Then
'Condition where more than one Home address exists updated on the same date
If (rsMaxAddressImportID.RecordCount > 1) Then
rsMaxAddressImportID.Close
strSql2 = "SELECT Addr_ImportID FROM [Non-Preferred Home Addresses] WHERE CnAdrAll_1_IDKEY = " & _
"(SELECT Max(CnAdrAll_1_IDKEY) FROM [Non-Preferred Home Addresses] WHERE CnBio_ID = '" & rs(0) & "' AND Addr_Type = 'Home');"
Set rsMaxAddressImportID = DBEngine(0)(0).OpenRecordset(strSql2, dbOpenDynaset)
MsgBox "Row = " & i
End If
'rsMaxAddressImportID.Close
Else
'Condition if all non-preferred addresses are not Home
rsMaxAddressImportID.Close
'Select max date last updated for next select statement
maxDateSql = "SELECT Max(CnAdrAll_1_DateLastChanged) " & _
"FROM [Non-Preferred Home Addresses] WHERE CnBio_ID = '" & rs(0) & "';"
Set rs2 = DBEngine(0)(0).OpenRecordset(maxDateSql, dbOpenDynaset)
strSql2 = "SELECT Addr_ImportID FROM [Non-Preferred Home Addresses] " & _
"WHERE [Non-Preferred Home Addresses].CnBio_ID = '" & rs(0) & "' " & _
"AND [Non-Preferred Home Addresses].CnAdrAll_1_DateLastChanged = #" & rs2(0) & "#;"
Set rsMaxAddressImportID = DBEngine(0)(0).OpenRecordset(strSql2, dbOpenDynaset)
'MsgBox rsMaxAddressImportID(0)
If Not (rsMaxAddressImportID.EOF) Then
'MsgBox rsMaxAddressImportID.RecordCount
If (rsMaxAddressImportID.RecordCount > 1) Then
rsMaxAddressImportID.Close
strSql2 = "SELECT Addr_ImportID FROM [Non-Preferred Home Addresses] WHERE CnAdrAll_1_IDKEY = " & _
"(SELECT Max(CnAdrAll_1_IDKEY) FROM [Non-Preferred Home Addresses] WHERE CnBio_ID = '" & rs(0) & "' AND CnAdrAll_1_DateLastChanged = #" & rs2(0) & "#);"
Set rsMaxAddressImportID = DBEngine(0)(0).OpenRecordset(strSql2, dbOpenDynaset)
'MsgBox rsMaxAddressImportID(0)
End If
End If
End If
'Get Actual address line
'DoCmd.RunSQL "SELECT * INTO " & _
"[Tbl_Max_Non-Preferred_Address] " & _
"FROM [Non-Preferred Home Addresses] WHERE [Non-Preferred Home Addresses].Addr_ImportID = '" & rsMaxAddressImportID(0) & "';"
DoCmd.RunSQL "INSERT INTO [Tbl_Max_Non-Preferred_Address] SELECT * FROM [Non-Preferred Home Addresses] WHERE [Non-Preferred Home Addresses].Addr_ImportID = '" & rsMaxAddressImportID(0) & "';"
rsMaxAddressImportID.Close
rs.MoveNext
i = i + 1
Loop
Else
MsgBox "There are no records in the recordset."
End If
rs.Close
- The significance of "Home" address is, some Constituents do not have a "Home" address (see CnBio_ID 1223144).
- rs is a Selection of unique CnBio_IDs to loop through.
Update after solution by Thomas G:
Overall, everything seems to get a good result, but I think there is sorting/order by issue going on and I can't seem to get the syntax correct to test. I keep getting a syntax error. I'm not familiar enough with access interpretation of parenthesis, etc. to get it right. I'm trying to run the following:
strSql_1 = "INSERT INTO [Table1] SELECT 1 AS priority, T1.CnBio_ID, T2.Max_Date, MAX(T1.Addr_IDKEY) AS MAX_IDKey " & _
"FROM [TB - Non-Preferred Addresses] T1 " & _
"INNER JOIN " & _
"(" & _
"SELECT CnBio_ID , MAX(CnAdrAll_1_DateLastChanged) AS Max_Date " & _
"FROM [TB - Non-Preferred Addresses] " & _
"WHERE (Addr_Type = 'Home' AND CnBio_ID = '0106228') " & _
"GROUP BY CnBio_ID " & _
") T2 ON T1.CnBio_ID = T2.CnBio_ID AND T1.CnAdrAll_1_DateLastChanged = T2.Max_Date " & _
"WHERE Addr_Type = 'Home' " & _
"GROUP BY T1.CnBio_ID, T2.Max_Date "
strSql_2 = " UNION ALL SELECT 2 AS priority, T1.CnBio_ID, T2.Max_Date, MAX(T1.Addr_IDKEY) AS MAX_IDKey " & _
"FROM [TB - Non-Preferred Addresses] T1 " & _
"INNER JOIN " & _
"(" & _
"SELECT CnBio_ID , MAX(CnAdrAll_1_DateLastChanged) AS Max_Date " & _
"FROM [TB - Non-Preferred Addresses] " & _
"WHERE (Addr_Type IN ('Campus','Harris Home', 'NCOA2003','Other','Previous','Previous Home','Previous Student','Seasonal','Student') AND CnBio_ID = '0106228') " & _
"GROUP BY CnBio_ID " & _
") T2 ON T1.CnBio_ID = T2.CnBio_ID AND T1.CnAdrAll_1_DateLastChanged = T2.Max_Date " & _
"WHERE (Addr_Type IN ('Campus','Harris Home', 'NCOA2003','Other','Previous','Previous Home','Previous Student','Seasonal','Student') AND T1.CnBio_ID = '0106228') " & _
"GROUP BY T1.CnBio_ID, T2.Max_Date " & _
"ORDER BY CnBio_ID, priority"