最近被一个简单的SQL问题吊打,强颜欢笑
好了正文开始
一问:SQL中的 group by 和 distinct 了解吗,简单介绍一下?
了解了解,“Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理。
distinct是一个关键字,常用于select之后,用于取出去重之后的值。
追问:可以可以,那你能描述一下它俩之间的关系吗?
(之前一直没注意过group by和distinct之间还有关系...)
其实仔细想想,group by是分组合并,既然分组就会“减少”一部分数据;distinct主要是去重操作,同样也会减少一部分数据,既然都会减少一部分数据,这是不是就是他们的共通之处??
所以,group by 和 distinct 都可以用于去重。那有什么区别呢?
简单创建一个测试表object,有两个字段编号no和名字name,添加一些数据,如图1所示,要求去重输出,输出结果为【1001 狗哥】和【1002 小盒】。
分别测试如下SQL语句:
SELECT DISTINCT name
FROM object
-----------------------------------
SELECT DISTINCT name, no
FROM object
可以发现,当单独对name字段去重后,输出如下图图2所示:
确实达到了对name字段去重的效果,可是要是使用 "SELECT DISTINCT name,no"语句,会发现输出结果如图3所示
仔细对比图一发现,只有两个字段完全一样的数据【1001 狗哥】被去掉,其他只有一个字段重复的数据并没有变化。其实这就反映了一个事实:distinct主要是针对全部字段去重,即去掉完全一样的数据。
要想每个字段只保留同一个值,即针对单字段去重,也就是题目中所要求的输出【1001 狗哥】和【1002 小盒】,可以采用group by聚合去重,代码如下:
SELECT no, name
FROM object
GROUP BY name
输出结果如图4所示,达到最初目的:
总结
distinct和group by都可以用来去重,不同之处是distinct针对全部字段去重,而group by可以针对全部字段中的单一字段去重。
此外,两者执行方式不同,distinct主要是对数据两两进行比较,需要遍历整个表。group by分组类似先建立索引再查索引,当数据量较大时,group by速度要优于distinct。
所以在实际应用中,经常会采用group by去重,比如计算独立访客数UV,独立IP数和用户留存率时,都需要对用户id等信息去重,采用group by可以大幅缩短时间。