数据盲目分析(五)——你的担架呢?|周末学习

226 阅读2分钟

这是我参与更文挑战的第5天,活动详情查看:更文挑战

本文已参与 周末学习计划,点击查看详情

我的担架

本系列在第一篇文章的时候说过会穿插一些sql来和pandas做对比 ,没想到这么快就可以兑现了。

相对于pandas,sql似乎被使用的更加的广泛。因此熟练的掌握sql,也是助力里在职场快乐摸鱼(划掉)高效率工作的利器。

回顾案例

需求如下:

  • 找到小明和李晓华计分不同的学号
  • 对计分错误的学生的各科成绩进行分组求和。
select 
select a.id,sum(danke_score.score) from 
(select panel.id from panel where score1 != score2) a
inner join danke_score 
on a.id = danke_score.studentid
group by studentid

啊有点长啊

其实不是很长,还是从里往外看,

1,通过一行select 获取计分不同的id,也就是学号

2,将两个表链接在一起

3,根据学号将score分组,并通过sum函数进行求和

这里简单说下join,关于left join inner join区别,我之前水文章时也写过,菜鸟教程也有,这里就不赘述了。写下这篇文章的时候,作者正因为一个sql跑十七分钟不出结果而烦恼。数据量大时,多个表互相join是一件很耗时的事。

那么我们怎么代替join呢

  1. 分多次select取不同表的数据,然后在自己的代码中自行实现join;

  2. 两个表各自存放自己数据的同时,做一张宽的冗余表,从宽表里取查询数据;

  3. 将需要Join的数据保存在缓存中(如redis),这也是面试题中系统设计的传统艺能了。

  4. 从独立的用户API接口进行读取。和方法1类似,在代码里做聚合。只是相当于把压力转移到另一个服务器上。

对于新增需求:每人科目最高分和次高分之和

是一个分组后排序的功能需求。

对于分组后排序,一般有两种思路,第一种是通过表的自连接,逐个查询比该条成绩高的成绩数量是否大于2,来判断是否是前两个高分的成绩。

这种思路不优雅所以略。

第二种是使用row_number()


select studentid,sum(score),row_number() over(partition by studentid order by score desc) as row_index
from danke_score 
group by studentid
where row_index<=2