Alors, dans ce genre de situation, le mieux est de prendre le problème à l'envers.
Tu vas d'abord trier tes données depuis l'historique et n'en prendre qu'un par ID.
Je tiens à préciser d'avance : Il y aura une sous-requête.
Premièrement on récupère la liste des ID qui nous intéressent, on en prend qu'un par sub_id, et on ne prend que le premier :
SELECT subHisto.id FROM abonnement_historique AS subHisto
GROUP BY subHisto.id_sub
ORDER BY subHisto.date_sub DESC;
PS : Ici, n'hésite pas à lancer la requête à côté et vérifier que tu as déjà les bons ID voulus.
On peut maintenant récupérer les id_sub qui lui sont lié et faire les jointures (mais dans l'autre sens) :
-- Ici, je met un alias pour être sûr et certain qu'on essaie pas de prendre dans la sous-requête
SELECT * FROM abonnement_historique AS histo
-- Attention, l'ordre est important ici
INNER JOIN abonnement ON histo.id_sub = abonnement.id_sub
INNER JOIN abonnement_client ON abonnement.email = abonnement_client.email
WHERE histo.id IN (
SELECT subHisto.id FROM abonnement_historique AS subHisto
GROUP BY subHisto.id_sub
ORDER BY subHisto.date_sub DESC
)
-- On trie à nouveau pour l'ordre d'affichage
ORDER BY histo.date_sub DESC;
Tu devrais maintenant avoir la dernière ligne de chaque abonnement avec les informations clients qui lui sont liées.
Après, à partir du moment où tu as ton tri, tu peux faire la requête dans le sens que tu préfères :
SELECT * FROM abonnement
INNER JOIN abonnement_client ON abonnement.email = abonnement_client.email
INNER JOIN abonnement_historique as histo ON histo.id_sub = abonnement.id_sub
WHERE histo.id IN (
SELECT subHisto.id FROM abonnement_historique AS subHisto
GROUP BY subHisto.id_sub
ORDER BY subHisto.date_sub DESC
)
-- On trie à nouveau pour l'ordre d'affichage
ORDER BY histo.date_sub DESC;