Sql 具有左联接的查询未返回计数为0的行
我试图通过以下方式为每个使用PostgreSQL中的左连接的组织返回计数,但我无法找出它不起作用的原因:Sql 具有左联接的查询未返回计数为0的行,sql,postgresql,count,left-join,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 =
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
使用合并似乎不起作用。我已经智穷了!任何帮助都将不胜感激
为了澄清什么不起作用,目前查询只返回计数大于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)
修复左连接
这应该起作用:
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
GROUP BY o.name
ORDER BY o.name;
您有一个左[外]连接,但后来的条件使它像一个普通的[内]连接。
将条件移动到JOIN子句以使其按预期工作。这样,只有满足所有这些条件的行才会在第一个位置连接,而右表中的列则填充为NULL。正如您所看到的,连接的行实际上在左连接之后进行附加条件测试,如果没有通过,则删除,就像普通连接一样
count一开始从不返回NULL。这是聚合函数在这方面的一个例外。因此,即使有额外的参数,coalesccountcol也毫无意义
应该注意的是,除了count之外,这些函数在未选择任何行时返回空值
我的。见:
计数必须在定义为不为NULL的列上,如e.id,或者联接条件保证示例中使用的e.Organization\u id、e.item\u template\u id或e
因为used是boolean类型,所以表达式e.used=true是燃烧为仅使用e.used的噪波
由于o.name未定义为UNIQUE not NULL,因此您可能希望按o.id分组,而不是将id作为主键-除非您打算折叠包含NULL的同名行
先聚合,后加入
如果在该过程中计算了大部分或所有行的考试项目,则此等效查询通常会更快/更便宜:
选择o.id、o.name作为组织名称,e.total\U使用
来自
左连接
选择Organization_id AS id-alias以简化连接语法
,count*AS total_used-count*=最快计数
来自考试项目
其中item_template_id={sanitizeitem_template_id}
使用
按1分组
e使用id
按o.name、o.id订购;
这是假设您不想像上面提到的那样折叠具有相同名称的行-典型情况
现在我们可以在子查询中使用更快/更简单的count*,并且在外部选择中不需要groupby
见:
说清楚了,
重要的一行由主_表分组,主_表将处理某个_表中的空值
coalesceCOUNTexam_items.id,0作为总使用量???是的,我也尝试过COUNTexam_items.id作为总使用量,但我不得不说sql并不是我的强项!对不起,我明白你的意思了!我已经试过了,但仍然不走运:/发布问题时,请说明问题中不起作用的含义-不返回任何内容、返回错误值、产生错误等。不相关,但仍然很重要:组织id整数引用organisationsid@wildplasser当前位置那一个被最好的错过了。这是一个鬼鬼祟祟的问题。我想,这基本上是一个风格/品味问题。就我个人而言,我永远不会写这样一行我希望;-就像只合并一个论点是没有意义的。缺少相关名称/别名让我感到困惑。@wildplasser:我总是先格式化和清理查询,然后才试图理解文本堆。我也是。正常地这就是我喜欢CTE的真正原因,但如果我认为我在一次阅读过程中遇到了问题,我会非常高兴触发。以防计数得到的是1而不是0:计数函数中指定的列很重要。
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