Je dirais que vous n'avez pas tout à fait stocké suffisamment de données dans votre table.
Dans l'état actuel des choses, vous devrez toujours examiner chaque paiement précédent pour déterminer si l'actuel est actif ou en attente d'activation, un impact important sur les performances et une requête plus complexe.
Un expires_at
calculé colonne pour les payments
, qui est calculé sur l'ajout d'un nouveau paiement sous la forme MAX(payments.expires_at) + INTERVAL service_plans.days DAYS
vous permettra de calculer le nombre de jours restants en ne regardant qu'une seule ligne... et si un utilisateur est sur un plan ou non.