我正在尝试计算从 MySQL 连接表返回的行数,即:
select *, count(pets.id) as pets_per_owner
from owners
left join pets
on owners.id=pets.owner_id
问题是所有连接的行都被分组。
有没有办法获得这些小计,但显示所有返回的行(未分组)而不单独查询?
TIA
问题是您使用的聚合函数没有GROUP BY
,因此结果被缩减为一行。
MySQL 使用 GROUP BY 的扩展,它允许选择列表中的列出现在聚合函数或 GROUP BY 子句之外,但这可能会导致意外结果。(参见MySQL 对 GROUP BY 的扩展)
来自 MySQL 文档:
MySQL 扩展了 GROUP BY 的使用,以便选择列表可以引用未在 GROUP BY 子句中命名的非聚合列。...您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这主要在每个未在 GROUP BY 中命名的非聚合列中的所有值对于每个组都相同时很有用。服务器可以从每个组中自由选择任何值,因此除非它们相同,否则选择的值是不确定的。此外,从每个组中选择值不会受到添加 ORDER BY 子句的影响。在选择了值之后对结果集进行排序,并且 ORDER BY 不会影响服务器选择的值。
为了解决这个问题,您应该做两件事,首先将 替换为select *
您需要返回的列的实际名称。其次,对您包含在选择列表中但未聚合的列使用 GROUP BY。例如:
select owners.name, count(pets.id) as pets_per_owner
from owners
left join pets
on owners.id=pets.owner_id
group by owners.name
由于您在评论中发布了代码,因此很难准确确定您要查找的内容,但如果您想要宠物名称和总数,您可以使用以下方法之一:
select o.name,
p.name pet_name,
p2.pets_per_owner
from owners o
left join pets p
on o.id = p.owner_id
left join
(
select owner_id, count(*) pets_per_owner
from pets
group by owner_id
) p2
on o.id = p2.owner_id
and p.owner_id = p2.owner_id;
或者您可以使用 GROUP_CONCAT 函数在一行中列出宠物名称:
select owners.name,
group_concat(pets.name separator ', ') pet_name,
count(pets.id) as pets_per_owner
from owners
left join pets
on owners.id=pets.owner_id
group by owners.name;