【mysql哪些事儿】distinct 和 group by用法总结

   需求是这样的,因为公司现在统计这一块做的不是十分完善,所以每天老板那边会需要根据各种条件的数据统计,因为用户达到了千万级别,所以每次统计查询其消费数据的时候,数据量,都需要手动导出数据来,将这些数据拼接起来,然后做成excel表格的形式,上报给boss。

    原来一直是另一个同事做,但是昨天同事不在,所以任务就落在了我的身上。经过和其他同事请教,发现这里面很多问题需要注意。第一,这些数据设计到5张表,每张表的数据量都特别大,所以如果联表查询的话,那么执行效率会很慢,所以建议单表查询,然后再将数据合并。第二,这些数据需要及时的保存和处理,以备下次使用。

    好久不写sql,这次又学习了一遍。


一、distinct 去重


    在mysql中,有时候需要查询某个字段不重复的记录,这个月可以使用关键字distince关键字来过滤重复的记录。在实际的生活中,经常也会使用count(distinctId)来返回不重复字段的条数。

查询语句:

-- 根据用户名称来去重
SELECT  DISTINCT  t.userName  FROM t_user t

执行结果如下:

 (2)作用于多列

-- 根据用户名称和年龄两个字段去重
-- 会过滤用户名称和ID都重复的字段,(只有username和age都相同的才会被过滤为一条)
SELECT  DISTINCT  t.userName,t.age FROM t_user t
(3)注意事项

distinct必须放在查询字段的开头,例如:

SELECT    t.userName,DISTINCT t.age FROM t_user t
会报错。

如果要查询不重复的记录,还可以使用group by进行分组。

(4)count(distinct userName) 可以返回不重复记录的条数

-- 返回不重复记录的条数
SELECT count( DISTINCT  t.userName) FROM t_user t

二、group by语句


group by 是按照一个或者多个字段进行分组,字段值相同的为一组。可以作用于单个字段分组,也可以用于多个字段分组。

适用场景:

如果要用到group by,一般用到的就是“每这个字”,例如现在说明有个这样的表:每个班级有多少人,就需要用到分组这个关键字。


(1)group +group_concat()

 group_concat(字段名)可以作为一个输出字段来使用, 表示分组之后,根据分组结果,使用group_concat()来放置每一组的某字段的值的集合

-- group_concat()函数
-- 按照userID分组,然后查找每组内对应的记录ID
SELECT  t.id,GROUP_CONCAT(t.id) from t_user t  GROUP BY t.userId

(2) group by + 集合函数

通过group_concat()的启发,我们既然可以统计出每个分组的某字段的值的集合,那么我们也可以通过集合函数来对这个"值的集合"做一些操作


-- 根据userId分组,然后查找其平均年龄
SELECT  AVG(t.age) ,t.userId,t.userName FROM  t_user t GROUP BY t.userId

-- 根据userId分组,然后统计每组userid的数目
SELECT   COUNT(t.userId),t.userId,t.userName FROM  t_user t GROUP BY t.userId



(3)group by 按照多个字段分组

group by按照多个字段进行分组,只有两个字段都符合条件时,才会分组成功。

例如A表的数据如下:


-- 按照用户ID和用户age分组
SELECT * FROM  t_user  t GROUP BY  t.userId,t.age

执行结果如下:


(4)where --group by---- having 使用

每个字段有其不同的作用。

count()是属于聚合函数,聚合函数不能出现在where中。

where和group连用,但是效果和having是不同的,where必须放在group by前面,意思是先过滤,然后再次分组。

而having是必须在group by 之后连用,是分组后的过滤。


 ①常见的聚合函数
count(*):获取数量
sum():求和(这里要注意求和是忽略null值的,null与其他数值相加结果为null,所以可以通过ifnull(xxx,0)将null的值赋为0)
avg():求平均数
max():求最大值
min():求最小值

这些函数和其他函数的区别是,这些函数一般作用于多条记录上。


②当使用where ,group by ,having之后的执行顺序如下

例如:

select city, count(*),age from dbo.user where departmentID=2 group by city,age having age >40
第一执行where子句查询复合条件的数据, 第二使用group by子句对数据进行分组,第三对group by子句形成的组进行聚合函数计算每一组的值,第四用having子句去掉不符合条件的组。having子句限制的是组,而不是行。 where中不能够使用聚合函数,但是having子句中可以。

例如:

每个用户,count 总量大于30的记录

-- 查询总count > 30
SELECT  t.id,t.userId,t.userName,t.age ,SUM(count)  FROM  t_user t  GROUP BY  t.userId  HAVING SUM(count)>30

显示每个地区的总人口数和总面积.仅显示那些面积超过1000000的地区。

SELECT region, SUM(population), SUM(area)
        FROM bbc
        GROUP BY region
        HAVING SUM(area)>1000000
在这里,我们不能用where来筛选超过1000000的地区,因为表中不存在这样一条记录。(where子句中不能使用聚集函数)
相反,HAVING子句可以让我们筛选成组后的各组数据

③ 整个sql的执行顺序如下

select--->where ---> group by ---->having ---->order by

 参考文档:

sql中where、group by、having的用法和区别

sql中的 where 、group by 和 having 用法解析(having使用讲解特别详细)


小结

 总结实践,再学习,再总结,不断提升,注重细节。




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值