Input data
date | number |
---|---|
2024-11-02 | 1000 |
2024-11-03 | 500 |
2024-11-05 | 1000 |
2024-11-06 | 1000 |
2024-11-07 | 1000 |
2024-11-08 | 500 |
2024-11-14 | 1000 |
2024-11-15 | 1000 |
for a given date I want to get the streak (dates backward in a row where number is above/equals a certain threshold => in the examples always 1000)
Examples:
If I search using a date which doesn't appear in the data (for example, 2014-11-12), I want the result to be 0.
I would greatly appreciate your help. Thank you so much!
I have another example:
Input data
date | number |
---|---|
2024-12-10 | 1000 |
2024-12-13 | 1000 |
2024-12-14 | 1000 |
query for date 2024-12-14 should return 2 (count 14. 13.) There is a gap between 13. and 10. So the 10. should not count.
Streak
CTE will assign a row_number to all the dates where number is >= 1000.SELF JOINED
to find the dates which are consecutive and the number of days are counted based on difference of row numbers.EDIT
WITH streaks AS (
SELECT
t.date,
t.number,
ROW_NUMBER() OVER (ORDER BY t.date) AS rn
FROM test t
WHERE t.number >= 1000
),
consecutive_dates AS (
SELECT
s1.date,
COUNT(*) AS streak_length
FROM streaks s1
LEFT JOIN streaks s2
ON s2.rn <= s1.rn AND s2.date = s1.date - INTERVAL '1 day' * (s1.rn - s2.rn)
GROUP BY s1.date
)
SELECT
i.date,
COALESCE(cd.streak_length, 0) AS streak_length
FROM (SELECT '2024-11-13'::DATE AS date) i
LEFT JOIN consecutive_dates cd ON i.date = cd.date;
Output
date | streak_length |
---|---|
2024-11-13 | 0 |
EDIT : DATE contains timestamp, we just use the date portion from the timestamp.
WITH streaks AS (
SELECT
t.date::DATE AS date,
t.number,
ROW_NUMBER() OVER (ORDER BY t.date::DATE) AS rn
FROM test1 t
WHERE t.number >= 1000
),
consecutive_dates AS (
SELECT
s1.date,
COUNT(*) AS streak_length
FROM streaks s1
LEFT JOIN streaks s2
ON s2.rn <= s1.rn
AND s2.date = s1.date - INTERVAL '1 day' * (s1.rn - s2.rn)
GROUP BY s1.date
)
SELECT
i.date,
COALESCE(cd.streak_length, 0) AS streak_length
FROM (SELECT '2024-11-15'::DATE AS date) i
LEFT JOIN consecutive_dates cd ON i.date = cd.date;