首页 > 数据库 >解决PostgreSQL分组聚合时SELECT中字段必须在group或聚合函数中的问题(转自知乎仅供自己学习记录)

解决PostgreSQL分组聚合时SELECT中字段必须在group或聚合函数中的问题(转自知乎仅供自己学习记录)

时间:2023-06-20 11:12:12浏览次数:54  
标签:GROUP group name 中字段 score 聚合 class 函数

PG的分组函数是比较严格的。 你的select字段必须得存在于group子句、或者聚合函数中才行。

假设场景是这样的:

表结构name、class、score
我现在要按照name分组,聚合score数据,还能查出额外的这个 class 字段

如果是MySQL, 你可以直接group name 然后 select class,avg(score), 但是你在PostgreSQL里就不行。

他会爆出以下的错误

column “class” must appear in the GROUP BY clause or be used in an aggregate function

就是说这个 select class是非法的。

刚从MySQL切到PostgreSQL后很可能会比较难受这个点。

其实有一种很简单的方法, 那就是你反正其他的字段其实都一样,随便取一个就行,所以还是保持原来的GROUP BY 子句,然后直接给所有的字段全部加上一个 max() 函数就行了。

不过这样子的代价就是整个SQL看起来挺怪的, 语义上也有点微妙。我这只是个简单场景, 实际上你可能得有好几十个字段,这样子每个字段都得加上个max函数。

所以我推荐第二种方法。

Window function(窗口函数) + distinct 去重

窗口函数语法:

聚合函数(sum,min,avg……) + OVER ( …… )

窗口函数会将计算出来的结果带回到计算行上,还是以上面的例子作参考,一个表name、class、score。

那我直接一个普通查询,不GROUP了,我们想要的class自然就可以查出来了。

然后用窗口函数去算我需要聚合的数据,这里直接写上关键字OVER放在avg(score)后面, 然后括号里跟上一个PARTITION BY name, 意思就是按照name去分组,把结果计算出来。

唉!这个效果其实就和GROUP BY差不多,对不对。

不过这样子的话你数据是有了,但是行数却没变,原来是多少行现在还是多少行。 好,那我就直接给它安排一个 dictinct 函数,指定我 PARTITION BY 的那个字段,也就是name。

这样子我们就完成了一波上流且奢华的SQL查询,大功告成~

SELECT distinct on (name) 
    name,
    class,
    avg(score) OVER (PARTITION BY name) AS score,
FROM table

 

语义上清晰不少, 效果也给满足了(指按照name分组,聚合score数据,还能查出不处于GROUP子句和聚合函数中的 class 字段)

PS: OVER 后面的括号里可以什么都不填,那样子就是所有数据都会经过此窗口计算。

PS:其实还有一种连表/子查询的方法, 就是有点丑陋。这种大家应该都会,就不写了。

标签:GROUP,group,name,中字段,score,聚合,class,函数
From: https://www.cnblogs.com/Thenext/p/17493066.html

相关文章

  • 通过cgroup给docker的CPU和内存资源做限制
    1.cpudockerrun-it--cpu-period=100000--cpu-quota=2000ubuntu/bin/bash相当于只能使用20%的CPU在每个100ms的时间里只能使用20ms的计算时间2.内存$dockerrun-m1Gubuntu:16.04,该容器能使用的内存大小为1G,能使用的swap分区大小也为1G。容器内的进程能申请到的总内存......
  • Oracle列转行函数LISTAGG() WITHIN GROUP ()用法
    1:SELECTID,SIDFROMTestWHERE ID='001' 2:SELECTID,LISTAGG(SID,',')WITHINGROUP(ORDERBYSID)ASSID_LISTFROMTestWHERE ID='001'groupbyID  ......
  • UML中关联、聚合和合成
    摘自:sangmado-UML中关联(Association)、聚合(Aggregation)和合成(Composition)之间的区别元素名称符号图例含义Association A和B相互调用和访问对方的元素。AandBcallandaccesseachother’selements.AggregationA中拥有一个B,但B脱离于......
  • SQL聚合/多表/连接查询
    一、聚合查询使用SQL自带的聚合函数进行查询,有count()、AVG()、min()、max()、sum()二、分组聚合查询SELECTCity,Gender,COUNT(*)FROMStudentsGROUPBYCity,Gender;三、多表查询    ......
  • java 聚合项目--pom.xml配置文件
    java聚合项目创建聚合项目的2种方式:分层项目开发:1.DAO:java工程项目;(mavenquickstart)2.Service:java工程项目;(mavenquickstart)3.模型:java工程项目;(mavenquickstart)4.共工模块:java工程项目;(mavenquickstart)5.controller+view:webapp:web工程项目(mavenwebapp)工程类型:packing......
  • java 创建聚合项目的2种方式及 部署Nacos
    创建聚合项目的2种方式byIDEA20231.创建module,erp-parent2.创建子module,设置每个module的pom.xml属性pom及父模块;3.配置erp-parent模块里的pom.xml1.创建module,erp-parent2.创建子module--mavenarchet部署nacosype(archetype:quickstart(java工程),webapp(web工程),设置每......
  • cgroup cpu 子系统参数深入理解
    shares这个容易理解,无论cpuset.cpus中有多少个cpu,它都是按照比例用。cpu.cfs_quota_us这个就有点坑了,用起来会有些费劲。8核机器,aptasks里有20个线程并行执行,设置cpu.cfs_quota_us为30000(period为100000),预期是cpu能用到30%*8=240%,而实际上只用到了30%。也就是......
  • Elasticsearch专题精讲—— Aggregations —— Metrics aggregations(度量聚合)
    Aggregations——Metricsaggregations(度量聚合)https://www.elastic.co/guide/en/elasticsearch/reference/8.8/search-aggregations-metrics.html#search-aggregations-metricsTheaggregationsinthisfamilycomputemetricsbasedonvaluesextractedinone......
  • mongo聚合字符串类型的数字进行排序
    设置collationCollationcollation=Collation.of(Locale.CHINESE).numericOrdering(true);设置聚合选项Aggregationaggregation=Aggregation.newAggregation(Aggregation.match(orOperator),).withOptions(AggregationO......
  • Elasticsearch专题精讲—— Aggregations(聚合)
    Aggregations(聚合)https://www.elastic.co/guide/en/elasticsearch/reference/8.8/search-aggregations.html#search-aggregationsAnaggregationsummarizesyourdataasmetrics,statistics,orotheranalytics.Aggregationshelpyouanswerquestionsl......