关于postgresql group by 报错 的问题

关于postgresql group by 报错

【转载自】https://www.cnblogs.com/huangguoming/p/10732528.html

举个例子:
table name: makerar

cnamewmnameavg
canadazoro2.0000000000000000
spainluffy1.00000000000000000000
spainusopp5.0000000000000000

执行语句:
1 SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;

错误:

ERROR: column “makerar.wmname” must appear in the GROUP BY clause or be used in an aggregate function LINE 1: SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;

首先这个错误的原因是因为:
 
  Before SQL3 (1999), the selected fields must appear in the GROUP BY clause[*].Interestingly enough,even though the spec sort of allows to select non-grouped fields, major engines seem to not really like it.Oracle and SQLServer just don’t allow this at all. Mysql used to allow it by default, but now since 5.7 theadministrator needs to enable this option (ONLY_FULL_GROUP_BY) manually in the server configuration for this feature to be supported.

翻译过来就主要是:在SQL3(1999)标准之前,select 的字段必须也放在group by 的语句里(因为当如未 在group的相同字段出现不同值时,数据库引擎便不知道刚显示什么了,如上例)。主要的数据库引擎都不允 许这样的操作(有selected field 不放在group by中),即使mysql在5.7版本后也需要打开一个选项才能使用

这种操作在mysql上运行的情况:it doesn’t work “well” in mysql – in fact, they actually warn you in the docs that if you do it, and all the “hidden” columns (those not in the GROUP BY) aren’t 1-to-1 with the GROUP BY columns, then the results are unpredictable in every other database you just plain can’t do it, so i wouldn’t call what mysql does “doing it well”。

解决办法:

1. 先在子查询里进行聚合运算(sum,max等),在通过join连接

SELECT m.cname, m.wmname, t.mx FROM (SELECT cname, MAX(avg) 
AS mx FROM makerar GROUP BY cname) t 
JOIN makerar m ON m.cname = t.cname AND t.mx = m.avg ;
cnamewmnamemx
canadazoro2.0000000000000000
spainusopp5.0000000000000000

2.使用window functions

 1 SELECT cname, wmname, MAX(avg) OVER (PARTITION BY cname) AS mx FROM makerar; 
cnamewmnamemx
canadazoro2.0000000000000000
spainluffy5.0000000000000000
spainusopp5.0000000000000000

要去掉mx重复的话:

SELECT DISTINCT /* distinct here matters, because maybe there are  various tuples for the same max 
value */     m.cname, m.wmname, t.avg AS mx FROM (     SELECT cname, wmname, avg, ROW_NUMBER() 
OVER (PARTITION BY avg DESC) AS rn      FROM makerar ) t JOIN makerar m ON m.cname = t.cname AND 
m.wmname = t.wmname AND t.rn = 1 ;  
cnamewmnamemx
canadazoro2.0000000000000000
spainusopp5.0000000000000000

3.使用 DISTINCT ON

SELECT DISTINCT ON (cname) cname, wmname, avg FROM makerar ORDER BY cname, avg DESC;
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PostgreSQL中,当使用GROUP BY语句时,SELECT语句中的字段必须与GROUP BY子句中的字段匹配。这是因为在SQL3(1999)标准之前,数据库引擎无法确定在GROUP BY的情况下如何处理未在GROUP BY子句中列出的字段的值。如果SELECT语句中的字段没有正确地放置在GROUP BY子句中,就会导致报错。 对于你提到的错误,可能是因为SELECT语句中的字段没有正确地放置在GROUP BY子句中导致的。如果你移除了min和max函数,或者去掉其他字段,那么这个错误可能不会出现。 值得注意的是,大多数数据库引擎都不允许SELECT语句中的字段不在GROUP BY子句中的操作,即使在MySQL的5.7版本后也需要打开一个选项才能使用。 如果你在执行类似下面的语句时出现错误: SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname; 可能是因为cname或wmname字段没有在GROUP BY子句中列出所导致的错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [postgreSQL使用sql归一化数据表的某列,以及出现“字段 ‘xxx’ 必须出现在 GROUP BY 子句中或者在聚合函数...](https://blog.csdn.net/df1445/article/details/106783849)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [关于postgresql group by 报错问题](https://blog.csdn.net/tianbao668/article/details/112171774)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值