PostgreSQLで左結合を使用して、すべての組織のカウントを返すために以下を取得しようとしていますが、なぜ機能しないのかわかりません。
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
coalesce
を使用しても機能しないようです。私は機知が尽きました!どんな助けも確かに感謝されます!
何が機能していないかを明確にするために、現時点では、クエリは0より大きいカウントを持つ組織の値のみを返します。カウントに関係なくevery organisationの行を返したいと思います。
テーブル定義:
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)
これは動作するはずです:
_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;
_
_LEFT [OUTER] JOIN
_がありましたが、後のWHERE
条件により、プレーン__[INNER] JOIN
_のように動作しました。
条件をJOIN
句に移動して、意図したとおりに機能するようにします。この方法では、これらすべての条件を満たす行のみが最初に結合されます(またはrightテーブルの列はNULLで埋められます)。あなたが持っていたように、結合された行は追加条件について事実上テストされますafter the _LEFT JOIN
_そして、それらがパスしない場合は、プレーンなJOIN
と同様に削除されます。
COUNT()
は、最初からNULLを返すことはありません。この点で、集計関数の例外です。したがって、 neverは、パラメーターを追加しても意味があります。 マニュアル :COALESCE(COUNT(col))
count
を除き、行が選択されていない場合、これらの関数はnull値を返すことに注意してください。
大胆な強調鉱山。
明確にするために、
重要な行はGROUP BY MAIN_TABLE
SOME_TABLEからのNULL値を処理します
SELECT COUNT(ST.ID)
FROM MAIN_TABLE MT
LEFT JOIN SOME_TABLE ST ON MT.ID = ST.MT_ID
GROUP BY MT.ID