2013-03-17 70 views
24

我试图让下面的返回计数使用左每个组织参加PostgreSQL的计数返回行,但我想不通为什么它不工作:查询与LEFT JOIN不为0

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 

使用​​3210似乎不起作用。我在智慧的结尾!任何帮助肯定会感激!

要澄清什么是不起作用的,目前查询只返回具有大于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) 
+1

'聚结处理NULL值(COUNT(exam_items.id),0)作为total_used' ??? – wildplasser 2013-03-17 23:40:13

+0

好吧,我也试过COUNT(exam_items.id)作为total_used,但是我不得不说sql并不是我的特长! – mulus 2013-03-17 23:47:40

+0

对不起,我明白你的意思了!我已经尝试过了,但仍然没有运气:/ – mulus 2013-03-17 23:53:40

回答

42

这应该工作:

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 JOIN但后来WHERE条件迫使它是纯JOIN
    将条件向下拉入JOIN子句,使其按预期工作。通过这种方式,只有满足所有这些条件的行才会被加入(或者左侧的列被NULL填充)。否则(像你一样),连接的行进行测试的附加条件(实际上LEFT [OUTER] JOIN),并从结果中删除,如果他们不通过,就像一个普通的[INNER] JOIN

  • COUNT()永远不会返回NULL开头。在这方面,这是总体职能中的一个例外。因此, COALESCE(COUNT(col)) 从来没有是有道理的,即使有额外的参数。 Per documentation

    应当指出的是,除了count,当选择没有行这些函数返回一个空值。

大胆强调我的。

+0

啊,很好!我错过了exam_items上额外的where-clause元素... – wildplasser 2013-03-18 00:38:17

+3

ERWIN你是我的英雄!非常感谢! – mulus 2013-03-18 00:44:32

+0

@wildplasser:那一个已经错过了最好的。这是一个鬼祟的。 – 2013-03-18 00:45:10

7

要清楚,

重要线是GROUP BY MAIN_TABLE将从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