web-dev-qa-db-ja.com

LEFT JOINを使用したクエリで、カウントが0の行が返されない

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)
31
mulus

これは動作するはずです:

_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を返すことはありません。この点で、集計関数の例外です。したがって、 COALESCE(COUNT(col)) neverは、パラメーターを追加しても意味があります。 マニュアル

    countを除き、行が選択されていない場合、これらの関数はnull値を返すことに注意してください。

大胆な強調鉱山。

61

明確にするために、

重要な行は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
9
Sruit A.Suk