SQL : avoir un décompte égal à zéro s pas de correspondance avec LEFT JOIN

Récemment pour un projet, j’ai eu à faire une série de diagramme voir image ci-dessous :

Deux périodes avec des données pas toujours consistentes, des barres de taille hétérogène, pas top pour l’affichage. On veut la taille des barres constantes, donc forcer l’affichage des données même si le décompte est zéro.

Le soucis c’est que chaque mois, on n’a pas forcément chaque libellé, donc les données qui sont fournit avec une requête inner join, ne retourne rien, et j’ai des fois deux barre au lieu de 5 voir plus.

Il fallait trouver un moyen de retourner tous les libellé, même si le décompte retournait 0.

Ainsi on aura des graphique plus harmonique, et pas des barre de différentes taille suivant les périodes.

Le technique : elle consiste à retourner dans un premier temps dans une sous requêtes des données faites avec un inner join, donc dans ce cas, on aura seulement deux barres, mais dans un second temps on va prendre le résultat de cette sous-requête et faire une jointure à nouveau avec la table de tous les libellé existants, mais cette fois ci avec un LEFT JOIN, ainsi on aura tous les libellés. Il faut voir le résultat de la sous requêtes comme une nouvelle table, c’est la clé de cette technique.

Requête d’origine menant au graphique présenté

SELECT count(*) as count, MD.ID_ETAT_MATRICE_DETAILS, MD.LIBELLE_ETAT_MATRICE_DETAILS as libelle 
FROM MATRICE M
LEFT JOIN ETAT_MATRICE_DETAILS MD on MD.ID_ETAT_MATRICE_DETAILS = M.ID_ETAT_MATRICE_DETAILS
 where M.ID_ETAT_MATRICE = 3 and M.DATE_SIGNATURE BETWEEN '2020-07-01' AND '2020-07-30' 
 AND USR_ID = '9999'
 GROUP BY MD.ID_ETAT_MATRICE_DETAILS;

Nouvelle requête en transformant en sous requête la requête actuelle, et en faisant une jointure avec la table des libellés

SELECT IFNULL(count,0), C.ID_ETAT_MATRICE_DETAILS , EMD.LIBELLE_ETAT_MATRICE_DETAILS 
	FROM ETAT_MATRICE_DETAILS EMD
	LEFT JOIN 
(SELECT count(*) as count, MD.ID_ETAT_MATRICE_DETAILS , MD.LIBELLE_ETAT_MATRICE_DETAILS as libelle 
FROM MATRICE M
INNER JOIN ETAT_MATRICE_DETAILS MD on MD.ID_ETAT_MATRICE_DETAILS = M.ID_ETAT_MATRICE_DETAILS
 where M.ID_ETAT_MATRICE = 3 and M.DATE_SIGNATURE BETWEEN '2020-07-01' AND '2020-07-30' 
 AND USR_ID = '9999'
 GROUP BY MD.ID_ETAT_MATRICE_DETAILS)  
 C on C.ID_ETAT_MATRICE_DETAILS = EMD.ID_ETAT_MATRICE_DETAILS
 WHERE EMD.ID_ETAT_MATRICE = 3;

Notez que j’ai forcé à zéro le décompte si il vaut null (en effet LEFT JOIN retourne une données même s’il n’y a pas de correspondance, donc ça devient NULL.)

Vous aimerez aussi...