i would like to count the entries of my record table, filtered by a given period by valid_from and valid_till or if valid_till is null
Records
| id | name | valid_from | valid_till |
|---|---|---|---|
| 1 | A | 2022-07-01 | 2022-07-05 |
| 2 | B | 2022-07-02 | 2022-07-05 |
| 3 | C | 2022-07-02 | 2022-07-04 |
| 4 | D | 2022-07-03 | null |
| 5 | E | 2022-07-03 | 2022-07-03 |
Now let's assume that I get the following period (2022-06-30 to 2022-07-07) from the client. Now I want to find out all records that match this time period and the number of hits for each date in this period, not only for valid_from and valid_till.
I expect the following results:
| date | matches |
|---|---|
| 2022-06-30 | 0 |
| 2022-07-01 | 1 |
| 2022-07-02 | 3 |
| 2022-07-03 | 5 |
| 2022-07-04 | 4 |
| 2022-07-05 | 3 |
| 2022-07-06 | 0 |
| 2022-07-07 | 0 |
Furthermore, I would like to extend the whole scenario by knowing how many matches have already been read by the current user. For this, there is an additional table that holds the information per user and per record.
Viewstates
| id | record | user |
|---|---|---|
| 1 | 1 | X |
| 2 | 1 | Y |
| 3 | 2 | X |
| 4 | 3 | Y |
| 5 | 4 | X |
| 6 | 4 | Y |
| 7 | 4 | Z |
| 8 | 5 | X |
| 9 | 5 | Y |
| 10 | 5 | Z |
Assuming I am now user X then I would expect the following result:
| date | matches | already_read_by_me |
|---|---|---|
| 2022-06-30 | 0 | 0 |
| 2022-07-01 | 1 | 1 |
| 2022-07-02 | 3 | 2 |
| 2022-07-03 | 5 | 4 |
| 2022-07-04 | 4 | 3 |
| 2022-07-05 | 3 | 3 |
| 2022-07-06 | 0 | 0 |
| 2022-07-07 | 0 | 0 |
Unfortunately, I currently really have no idea how to implement and solve this.
My actually coding attempt looks like that
SELECT
COUNT(r.id) as matches,
COUNT(vs.record_id) as already_ready_by_me
FROM
records r
LEFT JOIN
(
SELECT id AS viewstate, record_id FROM viewstates WHERE user = 'xxx'
) vs ON r.id = vs.record_id
WHERE
r.valid_from >= '2022-07-01'
AND (r.valid_till <= '2022-07-10' OR r.valid_till IS NULL)
ORDER BY
valid_from
DESC;
Hope here is someone who can help me.
Thanks a lot.
BR, Sven