I’m working on a monitoring system based on MySQL. The system consists of a table which records checks (e.g. a crawled website) for multiple users. The users shall be notified about their last failed (NOK) check but only once a week. So if multiple checks happen within a week a user shall get only one notification. If a check was good the status is OK. Otherwise it’s NOK.
Table "Checks":
id | userId | checkAt | status | notifiedAt |
---|---|---|---|---|
1 | 10 | 2024-07-31 | NOK | |
2 | 10 | 2024-07-30 | OK | |
3 | 10 | 2024-06-20 | NOK | 2024-06-21 |
4 | 20 | 2024-07-31 | NOK | |
5 | 20 | 2024-07-30 | NOK | 2024-07-30 |
Now I would like to notify each user about its latest NOK check. The latest NOK check shall be selected per user if there’s no other NOK check for the same user which has a notifiedAt date which is not older than 7 days. This is needed to prevent that a user gets notified more than once per week.
Comments about the example data:
- Let’s assume the query shall be executed on 2024-07-31
- Check-1 would be selected as it’s the most current check for user-10 with status NOK and the last notification for user-10 (check-3) lays more that 7 days in the past
- User-20 would not get a notification as he was notified about his last NOK check just one day before
Expected result:
id | userId | checkAt | status | notifiedAt |
---|---|---|---|---|
1 | 10 | 2024-07-31 | NOK |
I’ve tried a MySQL query with a group by userId but then I just have one record per user and I can’t compare the notifiedAt date to his previous NOK record.
My question is: Is it possible two resolve this selection with just one SQL query or how should I proceed?
Thanks in advance for a suggestion!
2
Answers
I think this query can work,
Since you want to notify the user once per week in case of NOK check status – it would be best to use WEEK() function. It is much more consistent then looking 7 days behind for each and every date.
WEEK() function allows you to define which day you want to consider as start of the week (check here)…
See the fiddle here.
NOTE:
If you have a case of checks containing data from multiple years you should, beside the week, add year to your conditions.