写在前文
- 作者简介:大家好,我是小王♂️
- 个人主页:你隔壁的小王
- 欢迎点赞+收藏⭐️+留言
- 专栏:SQL♂️
♂️ 小伙伴们如果在学习过程中有不明白的地方,欢迎评论区留言提问!希望能和大家一起进步,共同成长!
什么时候使用平均数、众数、中位数来分析数据那?在SQL中又应该怎么实现那?
SELECT UID, COUNT(*) AS cnt
FROM tb1
GROUP BY uid
HAVING COUNT(*) >= ( SELECT MAX(cnt)
FROM ( SELECT COUNT(*) AS cnt
FROM tb1
GROUP BY uid) TMP ) ;
可以看到已经取到该组数据中得众数,并且对其所出现的频次进行了统计
2、使用谓词
使用谓词的时候要考虑null的情况,否则容易出错,如果不考虑null的话就会把null进行分组,从而无法求得正确的众数
SELECT uid, COUNT(*) AS cnt
FROM tb1
where uid is not null
GROUP BY uid
HAVING COUNT(*) >= ALL ( SELECT COUNT(*)
FROM tb1
where uid is not null
GROUP BY uid
);
当平均值不可信时,与众数一样经常被用到的另一个指标是中位数(median)。它指的是将集合中的元素按升序排列后恰好位于正中间的元素。如果集合的元素个数为偶数,则取中间两个元素的平均值作为中位数。做法是,将集合里的元素按照大小分为上半部分和下半部分两个子集,同时让这 2 个子集共同拥有集合正中间的元素。这样,共同部分的元素的平均值就是中位数,思路如下所示。
SELECT AVG(DISTINCT uid) as 中位数
FROM (SELECT T1.uid
FROM tb3 T1, tb3 T2
GROUP BY T1.uid
HAVING SUM(CASE WHEN T2.uid >= T1.uid THEN 1 ELSE 0 END)
>= COUNT(*) / 2
AND SUM(CASE WHEN T2.uid <= T1.uid THEN 1 ELSE 0 END)
>= COUNT(*) / 2 ) a ;
要点在于比较条件“>= COUNT(*)/2”里的等号,这个等号是有意地加上的。加上等号并不是为了清晰地分开子集 S1 和S2,而是为了让这 2 个子集拥有共同部分。如果去掉等号,将条件改成“>
COUNT(*)/2”,那么当元素个数为偶数时, S1 和 S2 就没有共同的元素了,也就无法求出中位数了。