mysql group by over_sqlserver之group by 与over函数

group by 函数主要用来对数据进行分组,over()函数则是一个“开窗函数”,它更多的是与聚合函数如:sum()、max()、min()、avg()、count()等函数以及排名函数如:row_number()、rank()、dense_rank()、ntile()函数结合使用。

1.group by 函数

原始数据如下,数据表名为hr.employeee

a1e0bfcfe1e3d13b580d8ded57b55aed.png

对以上数据按照city字段进行分组,并计算了每组中存在的行数:

select city,count(city)asnfromhr.employeeegroup by city;

分组结果:

524dc41b1dd3cd1a9ae5212e8daa72bc.png

根据以上结果,London这个值在原始数据中出现了4次,该组的行数为4。

2.over()函数

一般来说,当使用了group by 进行分组查询,select查询阶段出现的columnlists如果没有出现在group by 后作为分组依据,就必须被包含在聚合函数中。但是往往在书写的时候就会忘记这个限制。over()函数则很好的解决了这个问题,该函数能够实现分组的效果。

原始数据如下(总共有830行):

5de503822867c7fc9ae3671179d27db7.png

进行以下查询:

select distinct val,row_number()over(order by val)asrownumfrom sales.ordervalues

315a43dc9aaaedaffec71e2dd71ab1ef.png

运行结果仍然是830行,但实际该数据是存在5行的重复数据,所以说,明明在select阶段使用distinct取不同值,为何会没作用呢???

T-SQL语言基础这本书是这样解释的:row_number函数是在distinct子句之前处理的,当其为数据分配了唯一的行号后,再处理distinct子句,所以这时不会有任何重复的行。(还未理解透,distinct是对val做处理,只要val存在重复值就剔除呀,难道不是这样的吗?--因为distinct是对其后的两列数据进行去重的!)

这也说明,在同一select子句中不能同时使用distinct和row_number()函数,因为distinct会失效!!!

要想得到不含重复值的数据,可以进行以下查询:

select val,row_number()over(order by val)asrownumfromsales.ordervaluesgroup by val;

36f04e05178791ace150fefe3a3e517c.png

这个时候就筛除了5行重复数据。

以下情形值得注意:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

--代码1--分组之后计算每组的行数

select val,count(val)asnfromsales.ordervaluesgroup by val;--注意查看分组后val值,这时已经达到去重的效果了--代码2--利用over函数达到分组效果,partition by对某列字段分区

select val,count(val)over(partition by val )asnumfromsales.ordervalues--代码3--代码2和3进行对比,注意区别

select val,count(val)over(partition by val )asnumfromsales.ordervaluesgroup by val;

View Code

代码1:利用group by 子句进行分组查询,并计算了每组的行数,观察结果发现,group by起到了去重的功效。

4b9c96c9dcd7c83b17285dfc4949a03a.png

代码2:利用over函数达到分组效果,partition by对某列字段分区,并计算分区后每组的行数,这种情况下并没有去重的效果。

cf8e7795628fb71ae1b0a583f4cff492.png

代码3:由于group by 处理顺序优于select,前面说到group by具有去重功效,每组数据只有唯一值!因此再进行over函数计算每组行数只有一个结果。

119105606173e723ea506c65f055e7fe.png

再来一组查询对比,当在over函数中同时指定partition by 和order by 的字段为同一个时,排序失效:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

--按照val降序排列失效!!!

select val,count(val)over(partition by val order by val desc )asnumfromsales.ordervalues;select val,count(val)over(partition by val )asnumfromsales.ordervaluesorder by val desc ;

View Code

c6eb891c68f91499231f2fd2b4225c01.png

以上按照val降序排列失效的原因在于,partition by 分区后的数据即按照了一定的顺序(升序)排列了,再使用order by 排序就会失效(个人理解):

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

selectvalfromsales.ordervaluesselectvalfromsales.ordervaluesgroup by val;

View Code

05b25fb2692153ba82849b9fac73342a.png

d48416d35d36599641ec48f89f760982.png

以上对比查询看到,group by不仅具有去重功效,还有按照升序排列数据的功能(单列数据查询)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值