J'essaie d'obtenir ce qui suit pour retourner un nombre pour chaque organisation utilisant une jointure gauche dans PostgreSQL, mais je ne peux pas comprendre pourquoi cela ne fonctionne pas:
select o.name as organisation_name,
coalesce(COUNT(exam_items.id)) as total_used
from organisations o
left join exam_items e on o.id = e.organisation_id
where e.item_template_id = #{sanitize(item_template_id)}
and e.used = true
group by o.name
order by o.name
L'utilisation de coalesce
ne semble pas fonctionner. Je suis à bout de souffle! Toute aide serait certainement appréciée!
Pour clarifier ce qui ne fonctionne pas, pour le moment, la requête ne renvoie que des valeurs pour les organisations dont le nombre est supérieur à 0. J'aimerais qu'il renvoie une ligne pour chaque organisation, quel que soit le nombre.
Définitions des tableaux:
TABLE exam_items
id serial NOT NULL
exam_id integer
item_version_id integer
used boolean DEFAULT false
question_identifier character varying(255)
organisation_id integer
created_at timestamp without time zone NOT NULL
updated_at timestamp without time zone NOT NULL
item_template_id integer
stem_id integer
CONSTRAINT exam_items_pkey PRIMARY KEY (id)
TABLE organisations
id serial NOT NULL
slug character varying(255)
name character varying(255)
code character varying(255)
address text
organisation_type integer
created_at timestamp without time zone NOT NULL
updated_at timestamp without time zone NOT NULL
super boolean DEFAULT false
CONSTRAINT organisations_pkey PRIMARY KEY (id)
Cela devrait fonctionner:
SELECT o.name AS organisation_name
, COUNT(e.id) AS total_used
FROM organisations o
LEFT JOIN exam_items e ON e.organisation_id = o.id
AND e.item_template_id = #{sanitize(item_template_id)}
AND e.used = true
GROUP BY o.name
ORDER BY o.name;
Vous aviez un LEFT [OUTER] JOIN
Mais les dernières conditions WHERE
l'ont fait agir comme un simple [INNER] JOIN
.
Déplacez la ou les conditions dans la clause JOIN
pour la faire fonctionner comme prévu. De cette façon, seules les lignes qui remplissent toutes ces conditions sont jointes en premier lieu (ou les colonnes de la table à droite sont remplies de NULL). Comme vous l'avez fait, les lignes jointes sont testées pour des conditions supplémentaires virtuellement après le LEFT JOIN
Et supprimées si elles ne passent pas, tout comme avec un simple JOIN
.
COUNT()
ne renvoie jamais NULL pour commencer. C'est une exception parmi les fonctions agrégées à cet égard. Donc, jamais est logique, même avec des paramètres supplémentaires. Le manuel :COALESCE(COUNT(col))
Il convient de noter que à l'exception de
count
, ces fonctions renvoient une valeur nulle lorsqu'aucune ligne n'est sélectionnée.
Accentuation mienne.
Pour être clair,
la ligne importante est GROUP BY MAIN_TABLE
qui gérera la valeur NULL de SOME_TABLE
SELECT COUNT(ST.ID)
FROM MAIN_TABLE MT
LEFT JOIN SOME_TABLE ST ON MT.ID = ST.MT_ID
GROUP BY MT.ID