PostgreSQL中JOIN后GROUP BY仅用主键未含非聚合列为何不报错?
PostgreSQL GROUP BY 主键时无需列出非聚合列的原因
我在练习SQL时遇到一段查询语句,原问题是对会员按预订时长排名,查询语句如下:
select firstname, surname, hours, rank() over (order by hours desc) from (select firstname, surname, ((sum(bks.slots)+10)/20)*10 as hours from cd.bookings bks inner join cd.members mems on bks.memid = mems.memid group by mems.memid ) as subq order by rank, surname, firstname;
我的疑惑是:这段查询的子查询里,SELECT了firstname和surname这两个非聚合列,但GROUP BY只写了mems.memid,却没有报错?按之前学的知识,GROUP BY必须包含所有非聚合的显示列。是不是因为通过主键JOIN后,主键能唯一标识这些列,所以不用把它们加入GROUP BY?
没错,你的猜测完全正确。这是PostgreSQL的特性——当你GROUP BY的列是某个表的主键(或者具有唯一约束的列)时,该列可以唯一确定同表中其他所有列的值。
在这个例子里,mems.memid是cd.members表的主键,每个memid对应唯一的firstname和surname。当你按memid分组时,每个分组里的firstname和surname不会有多个不同的值,数据库可以明确知道该取哪一个值返回,所以不需要把这两个列加到GROUP BY子句里也能正常运行。
这种特性是符合SQL标准的扩展,目的是简化查询编写,避免在GROUP BY里重复列出所有依赖主键的非聚合列。
内容的提问来源于stack exchange,提问作者Ahmet İhsan Gül
相关产品推荐
相关产品推荐

