使用LEFT JOIN查询不返回计数为0的行

mul*_*lus 31 sql postgresql count left-join

我试图让以下内容为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
Run Code Online (Sandbox Code Playgroud)

使用coalesce似乎不起作用.我的智慧结束了!任何帮助肯定会受到赞赏!

为了澄清什么不起作用,目前查询只返回计数大于0的组织的值.我希望它为每个组织返回一行,而不管计数如何.

表定义:

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)
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 62

这应该工作:

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;
Run Code Online (Sandbox Code Playgroud)
  • 你有一个,LEFT [OUTER] JOIN但后来的WHERE条件使它像一个平原[INNER] JOIN.
    将条件移动到JOIN子句以使其按预期工作.这样,只有满足所有这些条件的行才会首先连接(或者表中的列填充为NULL).就像你拥有它一样,连接的行几乎LEFT JOIN它们之后进行了测试,如果它们没有通过就被移除,就像平原一样JOIN.

  • COUNT()永远不会返回NULL开始.在这方面,它是聚合函数中的一个例外.因此,即使有额外的参数,也没有意义.手册:COALESCE(COUNT(col))

    应该注意,除了之外count,这些函数在没有选择行时返回空值.

大胆强调我的.


Sru*_*Suk 10

为了说清楚,

重要的一行是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 -- this line is a must
Run Code Online (Sandbox Code Playgroud)