Necessidade de obter a quantidade de dias que um usuário concluiu um hábito seguido (streak). Isso significa a sequência mais recente (hoje ao contrário) e não necessariamente a sequência mais longa.
Com as seguintes datas inseridas, estou esperando 4
- 14/09/2023
- 15/09/2023
- 16/09/2023
- 17/09/2023
Esta consulta está retornando 1 consistentemente, onde estou errando?
SELECT s.habit, MAX(s.streak) AS currentStreak
FROM ( SELECT IF(@prev = o.habit_id AND o.date = @prevDate + INTERVAL 1 DAY
, @streak := @streak + 1
, @streak := 1
) AS streak
, @prev := o.habit_id AS habit
FROM ( SELECT t.habit_id
, DATE(t.created_at) AS `date`
FROM habit_progress_logs t
CROSS
JOIN (SELECT @prev := NULL, @prevDate := NULL, @streak := 1) i
GROUP BY t.habit_id, DATE(t.created_at)
ORDER BY t.habit_id, DATE(t.created_at)
) o
) s
WHERE s.habit = 4
GROUP BY s.habit
Você esqueceu de definir
@prevDate
para cada linha e está retornando a seqüência máxima em vez da seqüência mais recente.Se você estiver usando MySQL >= 8.0, poderá usar funções de janela , em vez da configuração obsoleta de variáveis de usuário em expressões :
O primeiro CTE nos dá o agrupamento da sequência de datas, usando DENSE_RANK() (
rnk
adicionado para ilustração):A segunda CTE faz o GROUP BY e adiciona o ROW_NUMBER() :
Se você está preso no MySQL < 8.0:
Aqui está um db<>fiddle