Delete All But... (1 Viewer)

marion34s

New member
Local time
Today, 18:25
Joined
Feb 7, 2020
Messages
22
Hello Access Braintrust,

I have a table [Project Costs] which will be regularly updated with the most current information from our accounting files. I have included a Report Date with each entry so that I can tell what is the most up-to-date info. I have been able to create a query that will show only the most recently reported entries:

Code:
SELECT
[Project Costs].ProjectID,
Max([Project Costs].[Report Date]) AS [Date_Reported]
FROM [Project Costs]
GROUP BY ProjectID

What I have not been able to figure out is how to DELETE all the records except for the most recent that is returned by that query.

I am most certainly open to any and all solutions to remove the older entries from the table. I do not need to "archive" the old data since it is no longer relevant once there are updated numbers and since the db is backed up before entering any of the updated information.

Thank you in advance once again!
 

Minty

AWF VIP
Local time
Today, 23:25
Joined
Jul 26, 2013
Messages
10,379
If you can successfully query what you need, why bother trying to delete the older data?
Are you running out of space or is something else making the removal of the data necessary?

If it really is a requirement to only keep the latest data then air code something like

Code:
DELETE  * FROM  yourTable WHERE [Report Date] NOT IN (SELECT

Max([Project Costs].[Report Date]) AS [Date_Reported]
FROM [Project Costs]
GROUP BY ProjectID)
Test it using a select version first to make sure it's finding the right records to delete.

Syntax guide and examples here https://www.fmsinc.com/MicrosoftAccess/query/snytax/delete-query.html#Delete_Query_SQL_Syntax
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 17:25
Joined
Feb 28, 2001
Messages
27,364
Minty beat me to it by a couple of minutes. Agree also with his advice to test it first by making the DELETE a SELECT. Then if it looks good, change the SELECT back to a DELETE.
 

marion34s

New member
Local time
Today, 18:25
Joined
Feb 7, 2020
Messages
22
If you can successfully query what you need, why bother trying to delete the older data?
Are you running out of space or is something else making the removal of the data necessary?

If it really is a requirement to only keep the latest data then air code something like

Code:
DELETE  * FROM  yourTable WHERE [Report Date] NOT IN (SELECT

Max([Project Costs].[Report Date]) AS [Date_Reported]
FROM [Project Costs]
GROUP BY ProjectID)
Test it using a select version first to make sure it's finding the right records to delete.

Syntax guide and examples here https://www.fmsinc.com/MicrosoftAccess/query/snytax/delete-query.html#Delete_Query_SQL_Syntax

Thank you Minty! I Tried the code that you suggested and received the error message pictured below.
1583247359888.png

"You have written a subquery that can return more than one field without using the EXISTS reserved word int he main query's FROM clause. Revise the SELECT statement of the subquery to request only one field.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 15:25
Joined
Oct 29, 2018
Messages
21,570
Hi. I would second the idea of keeping the older records in case you need to review them later. But, another approach to only keep new data is to simply "update" the table with the new data rather than keep adding to it.
 

marion34s

New member
Local time
Today, 18:25
Joined
Feb 7, 2020
Messages
22
Hi. I would second the idea of keeping the older records in case you need to review them later. But, another approach to only keep new data is to simply "update" the table with the new data rather than keep adding to it.

Hi DBguy,
Do you have a suggestion on how to make my entry form update or add to the table? That was actually my first idea but was not able to accomplish it after many frustrating hours of trial and error (lots of errors).
Thanks!
 

Minty

AWF VIP
Local time
Today, 23:25
Joined
Jul 26, 2013
Messages
10,379
Thank you Minty! I Tried the code that you suggested and received the error message pictured below.
View attachment 79528
"You have written a subquery that can return more than one field without using the EXISTS reserved word int he main query's FROM clause. Revise the SELECT statement of the subquery to request only one field.

You have left the project ID in the subquery. Look carefully at what I posted. Try this first
Code:
SELECT * FROM [Project Costs] WHERE [Report Date] NOT IN
(SELECT Max([Project Costs].[Report Date]) AS [Date_Reported]
FROM [Project Costs]
GROUP BY ProjectID)
 

marion34s

New member
Local time
Today, 18:25
Joined
Feb 7, 2020
Messages
22
You have left the project ID in the subquery. Look carefully at what I posted. Try this first
Code:
SELECT * FROM [Project Costs] WHERE [Report Date] NOT IN
(SELECT Max([Project Costs].[Report Date]) AS [Date_Reported]
FROM [Project Costs]
GROUP BY ProjectID)

Thank you for the clarification and the help so far! The SELECT did not return anything...
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 17:25
Joined
Feb 28, 2001
Messages
27,364
I'm thinking that there is another way if you wanted to do the deletions. Surely you have a project ID of some sort. Create two queries. By the way, I'm removing spaces from names because that way you don't need brackets. Just a suggesting in passing to save you complexity in typing.

Code:
Q1:  
SELECT  ProjectID, MAX(ReportDate) AS MaxDate FROM ProjectCosts GROUP BY ProjectID ;

Q2:  
DELETE * FROM ProjectCosts INNER JOIN Q1 ON  Q1.ProjectID = ProjectCosts.ProjectID WHERE Q1.MaxDate <> ProjectCosts.ReportDate ;

This will join up all records from a given project to the query showing the max date for each project. Then if the dates DON'T match (and for each project, only one WILL match), delete the record.

HOWEVER, unless you have tens of thousands of such records accumulating each day, keeping older records around for historical purposes isn't wrong.
 

marion34s

New member
Local time
Today, 18:25
Joined
Feb 7, 2020
Messages
22
I'm thinking that there is another way if you wanted to do the deletions. Surely you have a project ID of some sort. Create two queries. By the way, I'm removing spaces from names because that way you don't need brackets. Just a suggesting in passing to save you complexity in typing.

Code:
Q1: 
SELECT  ProjectID, MAX(ReportDate) AS MaxDate FROM ProjectCosts GROUP BY ProjectID ;

Q2: 
DELETE * FROM ProjectCosts INNER JOIN Q1 ON  Q1.ProjectID = ProjectCosts.ProjectID WHERE Q1.MaxDate <> ProjectCosts.ReportDate ;

This will join up all records from a given project to the query showing the max date for each project. Then if the dates DON'T match (and for each project, only one WILL match), delete the record.

HOWEVER, unless you have tens of thousands of such records accumulating each day, keeping older records around for historical purposes isn't wrong.

Thank you Doc_Man! I'm so close and please excuse my SQL/Access ignorance...

I am not receiving an error "Specify the table containing the records you want to delete." (image below) I thought it did - it looks like it does to me...
1583249541900.png
 

ebs17

Well-known member
Local time
Tomorrow, 00:25
Joined
Feb 7, 2020
Messages
1,995
SQL:
DELETE ProjectCosts.* FROM ProjectCosts INNER JOIN ...
Possibly also:
SQL:
DELETE DISTINCTROW ProjectCosts.* FROM ProjectCosts INNER JOIN ...

My suggestion for a one-step query:
SQL:
DELETE
FROM
   [Project Costs] AS P
WHERE
   EXISTS
      (
         SELECT
            NULL
         FROM
            [Project Costs] AS X
         WHERE
            X.ProjectID = P.ProjectID
               AND
            X.[Report Date] > P.[Report Date]
      )
 

theDBguy

I’m here to help
Staff member
Local time
Today, 15:25
Joined
Oct 29, 2018
Messages
21,570
Hi DBguy,
Do you have a suggestion on how to make my entry form update or add to the table? That was actually my first idea but was not able to accomplish it after many frustrating hours of trial and error (lots of errors).
Thanks!
Hi. I don't mean to confuse the topic; but since you asked, see if this article gives you any ideas on how to do that. Hope it helps...
 

marion34s

New member
Local time
Today, 18:25
Joined
Feb 7, 2020
Messages
22
Hi. I don't mean to confuse the topic; but since you asked, see if this article gives you any ideas on how to do that. Hope it helps...
Thanks DB_Guy! This was a good article to read - what I was struggling with was the settings for a form that would allow me to either append or update entries (that was my first thought as how to solve the problem from the OP which would have made the desire to delete old data moot). I just was not able to figure out how to get it to work so I started to explore other options to achieve the end product (of course I ran into difficulties with the alternatives too).
Thanks!
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 17:25
Joined
Feb 28, 2001
Messages
27,364
As EBS noted:

Code:
DELETE ProjectCosts.* FROM ProjectCosts INNER JOIN Q1 ON  Q1.ProjectID = ProjectCosts.ProjectID WHERE Q1.MaxDate <> ProjectCosts.ReportDate ;
 

theDBguy

I’m here to help
Staff member
Local time
Today, 15:25
Joined
Oct 29, 2018
Messages
21,570
Thanks DB_Guy! This was a good article to read - what I was struggling with was the settings for a form that would allow me to either append or update entries (that was my first thought as how to solve the problem from the OP which would have made the desire to delete old data moot). I just was not able to figure out how to get it to work so I started to explore other options to achieve the end product (of course I ran into difficulties with the alternatives too).
Thanks!
Hi. Thanks! Again, to avoid confusing the topic, I would suggest trying out all the other suggestions first until you can get something to work. Then later, if you want, we can go back to this topic to give it a try. I had the impression you "import" all the new data in a batch, which this approach would fit well, I think. But if you're simply adding one record at a time, we can also discuss that later. For example, rather than blindly entering the new data, you could try searching the table first for any existing record. If there is, update it; otherwise, feel free to add the new one. Cheers!
 

Users who are viewing this thread

Top Bottom