Struggling with ms-access’s flavor of SQL queries still, though I’ve made some progress (thanks to y’all). I have an event log table like this:
Logs Table
| logID (auto#) | modID (str) | relID (str) | DateTime (date) | TxType (short) |
|---|---|---|---|---|
| 1 | 1234 | 22.3 | 10/1/22 0800 | 6 |
| 2 | 1234 | 22.3 | 10/1/22 0900 | 7 |
| 3 | 1234 | 22.3 | 10/1/22 1000 | 13 |
| 4 | 1234 | 22.3 | 10/1/22 1100 | 15 |
| 5 | 4321 | 22.3 | 10/1/22 0830 | 1 |
| 6 | 4321 | 22.3 | 10/1/22 0930 | 13 |
| 7 | 4321 | 22.3 | 10/1/22 1030 | 15 |
| 8 | 4321 | 22.3 | 10/1/22 1130 | 13 |
| 9 | 1234 | 23.1 | 11/1/22 0800 | 1 |
| 10 | 1234 | 23.1 | 11/1/22 0900 | 15 |
| 11 | 1234 | 23.1 | 11/1/22 1000 | 13 |
| 12 | 1234 | 23.1 | 11/1/22 1100 | 15 |
| 13 | 4321 | 23.1 | 11/1/22 0830 | 13 |
| 14 | 4321 | 23.1 | 11/1/22 0930 | 7 |
| 15 | 4321 | 23.1 | 11/1/22 1030 | 13 |
| 16 | 4321 | 23.1 | 11/1/22 1130 | 15 |
What I need to do is:
- filter the table by relID, then
- count the number of modID’s that have a 15 txType as the last/most recent chronological event in their rows.
So ideally I’d filter e.g. by relID=23.1 and get these results (but not logID # 10 for example) and then count them:
| logID (auto#) | modID (str) | relID (str) | DateTime (date) | TxType (short) |
|---|---|---|---|---|
| 12 | 1234 | 23.1 | 11/1/22 1100 | 15 |
| 16 | 4321 | 23.1 | 11/1/22 1130 | 15 |
As part of another function I have been able to count any modID’s having a single txType successfully using
SELECT COUNT(*) FROM ( SELECT DISTINCT Logs.modID, Logs.relID FROM Logs WHERE ((Logs.relID='23.1') AND ((Logs.TxType=13))) );
Another stackoverflow user (exception – thanks!) showed me how to get the last event type for a given modID, relID combination using
SELECT TOP 1 TxType FROM Logs WHERE (((Logs.modID=[EnterModID])) AND ((Logs.relID=[EnterRelID]))) ORDER BY DateTime DESC;
But I’m having trouble combining these two. I know I can combine COUNT and GROUP BY but Access treats GROUP BY very particularly, and I’m not sure how to use SELECT TOP to get the latest events for each modID rather than just the latest events in the table, period.
Advertisement
Answer
This should give you the logID from the row with the latest DateTime for each combination of modIDand your target relID:
PARAMETERS which_relID Text(255);
SELECT DISTINCT
(
SELECT TOP 1 logID
FROM Logs
WHERE modID=l.modID AND relID=l.relID
ORDER BY [DateTime] DESC
) AS latest_modID
FROM Logs AS l
WHERE l.relID=[which_relID]
Use it as a subquery which you INNER JOIN to your Logs table. Note the subquery evaluates rows regardless of TxType. So have the parent query select only rows whose TxType = 15
PARAMETERS which_relID Text(255);
SELECT l2.*
FROM
Logs AS l2
INNER JOIN
(
SELECT DISTINCT
(
SELECT TOP 1 logID
FROM Logs
WHERE modID=l.modID AND relID=l.relID
ORDER BY [DateTime] DESC
) AS latest_modID
FROM Logs AS l
WHERE l.relID=[which_relID]
) AS sub
ON l2.logID=sub.latest_modID
WHERE l2.TxType=15;
Note I moved the PARAMETERS clause into the parent query. But you can eliminate it altogether if you believe it’s causing trouble.
DateTime is a reserved word. I enclosed it in square brackets to ensure Access understands we mean the name of an object.
Using your sample data, I get these 2 rows when I supply 23.1 for the query parameter:
| logID | modID | relID | DateTime | TxType |
|---|---|---|---|---|
| 12 | 1234 | 23.1 | 11/1/2022 11:00:00 AM | 15 |
| 16 | 4321 | 23.1 | 11/1/2022 11:30:00 AM | 15 |
I get a single row with 22.3 for the parameter:
| logID | modID | relID | DateTime | TxType |
|---|---|---|---|---|
| 4 | 1234 | 22.3 | 10/1/2022 11:00:00 AM | 15 |