公众号后台回复“图书“,了解更多号主新书内容

作者:胖里

来源:胖里的日常

都说21天养成一个习惯,这才第5天,我都快养成每天两道SQL题的习惯了。

事情是这样的,之前读了一本书,也给大家做了推荐,原文在这里:这几道SQL题我不会做......这本书的基础部分很快就读完了,而SQL题目实战部分却被我一再耽搁。既然自己无法积极主动,就索性组织了几个人,一起刷题,相互监督。

目前的刷题进展地很顺利,于我个人而言,不仅完成了我的刷题任务,且还从大家的解题方法里学到了新思路、新方法。这不,迫不及待地跟大家分享下。

本次分享包括三部分内容:书中的两道题目,交流群讨论的一道题目,最近刷题后的一些想法

一、书中的两道题目

题目1:

有一张商品优惠活动时间表product_promotion,包括字段commodity_id(商品DI):varchar,start_date(优惠活动起始日期):DATE,end_date(优惠活动结束日期):DATE。查询在2021年1月7日至2021年1月9日期间参与优惠活动的商品,输出商品ID。

输入与输出示例为:

题目看上去很简单吧!也确实很简单,一道简单题目,逻辑不复杂,只需要限定好筛选条件即可。

不过简单题目也会出现一些好玩的东西。比如没关注输出示例,未升序排列商品ID;比如信息满满,感觉小菜一碟,结果筛选条件漏了,输出变少了;再比如我仔仔细细写满了所有条件发现别人少我两个条件也写得超好。

##代码
select commodity_id
from product_promotion
where (start_date >= '2021-01-07' and end_date <= '2021-01-09')
or (start_date <= '2021-01-07' and end_date >= '2021-01-09')
or (start_date <= '2021-01-09' and end_date >= '2021-01-09')
or (start_date <= '2021-01-07' and end_date >= '2021-01-07')
order by commodity_id

我是这样写得,按我个人思路,写得不重不漏,但其实还能这样写。

##代码 from 不困
select commodity_id
from product_promotion
where (start_date <= '2021-01-07' and end_date >= '2021-01-07' )
or (start_date >= '2021-01-07' and start_date <= '2021-01-09')
order by commodity_id

哎,还能这样。

##代码 from ZRT
select commodity_id
from product_promotion
where end_date >= '2021-01-07' and start_date <= '2021-01-09'
order by commodity_id

限定条件是越来越少,这波操作可着实让我学到了,你们学到了吗?

题目2:

现有一张app累计下载情况表app_download,该表记录了应用商店中app累计下载次数的信息,包括三个字段,app_id(app ID):varchar,app_type(app类型):varchar,download(下载次数):int。查询不同类型app的平均下载次数,需将下载次数排在前10%与后10%的app排除在外。输出app_type(app类型),avg_download(平均下载次数)。

输入与输出示例为:

这是一道逻辑稍微有点复杂的题目,难度中等。这道题目在群里引发了热烈的讨论。

我是这样做的。

##注释(思路想法):
##1.按下载次数降序排序,剔除前10%和后10%
##2.按app类型求平均下载次数
-- 法1:以前的做法,通过排序和计数手动计算top位置
select app_type,round(avg(download),4) as avg_download -- 计算平均下载次数,保留4位小数
from
(select app_id ,app_type,download,row_number()over(order by download desc)/sum(1) over() as num --计算每个app_id的下载次数top位置from app_download
)as t
where num > 0.1 and num < 0.9 -- 排除前10%和后10%
group by app_type
order by app_type -- 排序-- 法2:知道ntile()函数后,用此函数进行分桶
select app_type,round(avg(download),4) as avg_sownload -- 计算平均下载次数,保留4位小数
from
(select app_id ,app_type,download,ntile(10) over(order by download desc) as num -- 分桶,计算每个app_id的下载次数top位置from app_download
)as t
where num > 1 and num < 9 -- 排除前10%和后10%
group by app_type
order by app_type -- 排序

很明显我为了证明我不是以前的我了,写了两种方法。第一种是我之前不太熟悉各种函数的时候,会选择用排序/总记录数的方式来求得百分比。第二种是我学会分桶函数后使用的一种“装逼”手法。

我以为我挺能了,但人外有人,山外有山,我把percnt_rank()cume_dist()函数忘记了,也不是,第二个函数我见都没见过(惭愧)。

总结来说。

1.读题很重要,不要忽略条件。当然此题目其实较为模糊,也没说下载次数就必须是降序排列呀?前后各10%包含与否也没说明。我们面对具体业务时需先明确需求。

2.重要的是思路,也就是你的逻辑,只要逻辑在,随便选个能实现的函数即可,当然实际工作中也需考虑效率

3.对于同一需求,使用不同函数时需要注意边界条件,避免出现数据错误(多选、少选问题)。

4.小注:此题目示例有10条数据不代表只有10条数据,不可耍滑头。

二、交流群讨论的一道题目

有天我在做一个业务需求,按照想法和逻辑,选了一种表连接的方式达到了目的。但突然不太满足,是否还有别的方法可实现呢?

晚些时候我便类比了一个例子发到群里,想看看大家的想法和解决方法。

题目要求为:输出每个uid的第一第二position。

输入与输出示例为:

我最初的解法是这样的。

-- 法1:
-- 思路:左表取第一个position(使用窗口函数),右表取第二个position(使用窗口函数),left join一下
select t1.uid,t1.position as position1,t2.position as position2
from
(select uid,positionfrom (select uid,position,row_number() over(partition by uid order by log_time) as rnk from tmp_table )as t where rnk = 1
)as t1 --第一个position
left join
(select uid,positionfrom (select uid,position,row_number() over(partition by uid order by log_time) as rnk from tmp_table )as t where rnk = 2
)as t2 -- 第二个position
on t1.uid = t2.uid

之后我也考虑了窗口函数,群里小伙伴们也恰好给到了类似的解题思路和方法。

-- 法2:
-- 思路:使用lead/lag实现取下一个position,取最近(最小)时间的记录(使用rank)
select uid,log_time,position as position1,lead(position)over(partition by uid order by log_time) as position2,row_number() over(partition by uid order by log_time) as rnk
from tmp_table
where rnk = 1-- 法3:
-- 先使用窗口函数排序,得到rank,使用case when对rank进行判断
select uid,max(case when rnk = 1 then position end) as position1 -- 使用max选出非空值,max(case when rnk = 2 then position end) as position2
from
(select uid,position,row_number() over(partition by uid order by log_time) as rnk from tmp_table
)as t
group by uid

这不就卷起来了吗?

注意:此例子只是我随便抽象出来的,不具有实际业务意义,有同学考虑到用户访问页面等实际情况,想到了需要去重,很严谨,具体业务要具体分析。

三、刷题后的一些想法

刷了4天的题目,收获颇丰。

一起刷题的几位同学都比较善于思考和总结,对于一个问题总有打破纱窗问到底之势。

也超喜欢这种思维碰撞的感觉,很刺激。同一个问题,大家的思路可能有一丢丢不一样,方法也不一样,但最终得到的结果却是一样的。

我有时候抽查大家的文档,同一个问题,有用表连接的,有用开窗函数的,有定义变量的。

就连从字符串中按照某种规则取子串,方法也不一样,多的是我没见过的,还需要学习的方法。是什么呢?先卖个关子,之后再找机会告诉大家~

◆ ◆ ◆  ◆ ◆
麟哥新书已经在当当上架了,我写了本书:《拿下Offer-数据分析师求职面试指南》,目前当当正在举行活动,大家可以用相当于原价5折的预购价格购买,还是非常划算的:
数据森麟公众号的交流群已经建立,许多小伙伴已经加入其中,感谢大家的支持。大家可以在群里交流关于数据分析&数据挖掘的相关内容,还没有加入的小伙伴可以扫描下方管理员二维码,进群前一定要关注公众号奥,关注后让管理员帮忙拉进群,期待大家的加入。管理员二维码:猜你喜欢● 卧槽!原来爬取B站弹幕这么简单
● 厉害了!麟哥新书登顶京东销量排行榜!
● 笑死人不偿命的知乎沙雕问题排行榜● 用Python扒出B站那些“惊为天人”的阿

分享两道易错的SQL题相关推荐

  1. 分享两道阿里P7究极难度算法题,满满干货指导

    缘起 深圳市腾讯计算机系统有限公司成立于1998年11月,是中国最大的互联网综合服务提供商之一,也是中国服务用户最多的互联网企业之一. 腾讯业务多元化,覆盖面广:社交.通信.娱乐全面开花.其中,腾讯Q ...

  2. 【2】二级C语言中那些易错的概念题

    本篇是这几天总结的C语言易错概念题,这些题往往就是因为概念不清而做错,而当我们对概念非常熟练时,又可以秒选.这些题其实都是强行记住就行了,概念不清也就是没记住嘛,因为这种题失分简直就太不值得了,因此有 ...

  3. android最新面试题及答案,分享两道阿里P7究极难度算法题

    前言 曾听过很多人说Android学习很简单,做个App就上手了,工作机会多,毕业后也比较容易找工作.这种观点可能是很多Android开发者最开始入行的原因之一. 在工作初期,工作主要是按照业务需求实 ...

  4. 小白看完都会了!分享两道阿里P7究极难度算法题,已拿offer入职

    一个朋友是前阿里人,37岁,离职后就职美团.以前投一个面一个,今年想跳槽,但没想到投十个能有两个面试机会就不错了,最后索性又回了阿里做架构. 他在面试的时候,碰见比自己大的面试官,态度和善,一般面试都 ...

  5. 997页字节跳动Android面试真题解析火爆全网,分享两道阿里P7究极难度算法题

    开头 经常有网友在知乎问答提两个问题:"现在学习移动开发还有前景吗?""开发还有什么可以研究的?".网友回复:"现在还学移动开发,如同49年加入国军. ...

  6. Android开发必须要会!分享两道阿里P7究极难度算法题,醍醐灌顶!

    前文 本文希望通过揭开一些 React 隐藏的技术细节, 来辅助对官方文档中某些概念的理解 读者可以将本文看做对官方文档的补充 行文方式我采用的是提问-解答的方式, 即先根据官方文档给出的使用规则, ...

  7. 软件测试笔试单选21道易错题(附答案解释)

    1.下面几种白盒测试技术,哪种是最强的覆盖准则() 语句覆盖 条件覆盖 判定覆盖 条件组合覆盖 六种覆盖方法中,覆盖准则由弱到强依次是语句覆盖.判定覆盖(分支覆盖).条件覆盖.判定/条件覆盖.条件组合 ...

  8. python实现pow函数(求n次幂,求n次方,分享两道阿里P7究极难度算法题

    解法2:根据奇偶幂分类(递归法,迭代法,位运算法) 如果n为偶数,则pow(x,n) = pow(x^2, n/2): 如果n为奇数,则pow(x,n) = x*pow(x, n-1). 递归代码实现 ...

  9. Splay(不是Spaly,也不是slay,附两道练(mu)习(ban)题)

    前两天学了Splay,个人感觉还是挺简单的,嗯--稍微讲讲吧,Splay的主要操作就是Splay(废话),但是最难写(想)的应该是rotate(旋转)吧,相信大家在翻到我的题解的时候一定已经看过许多题 ...

最新文章

  1. 程序员必备技能:如何画好架构图?
  2. mysql 导出gbk_mysqldump指定编码导出数据,GBK编码实践
  3. robotframework笔记5
  4. 计算机python程序设计导论,程序设计导论:Python计算与应用开发实践(原书第2版)...
  5. python 3 关于requests库的 text / content /json
  6. Java核心技术-具体的集合
  7. visual studio(vs)中项目解决方案的目录组织安排
  8. infobright与mysql_infobright与mysql常规引擎使用对比
  9. Python操作PostgreSQL数据库的方法
  10. Oracle常用函数
  11. Java | PTA练习:Employee类的层级结构
  12. 单位电脑禁用u盘_组策略禁止u盘_注册表禁止u盘
  13. 解决hadoop:未找到命令;hadoop:未找到命令问题
  14. 已知两个向量的夹角和其中一个向量,求另一个向量
  15. 微信网页授权:网页版(一)
  16. Hypermesh2D网格划分实例1
  17. 从CSDN转战博客园
  18. 数据看板--日报、周报、月报
  19. cometd java_Jetty cometd(Continuation)学习笔记
  20. 气象统计方法短期气候预测代码汇总

热门文章

  1. 郑州外国语学校计算机竞赛班,速转!2019全国五大学科竞赛河南省高中获奖排行,你的高中排在哪里?...
  2. 30行代码-使用预训练模型实现中英文翻译
  3. 去除字符串首尾字符随笔纪要
  4. C# async/awit 嵌套异步 执行顺序 分析
  5. 一种利用人参酒自动诊断失眠的仪器
  6. USB转串口参数配置功能
  7. 二本双非一战中科大成功上岸-经验分享
  8. 用calibre抓取乌云知识库并生成电子书
  9. 彻底理解Java内存模型,它为什么会引发线程安全问题【吐血总结】
  10. 2021年汽车驾驶员(初级)实操考试视频及汽车驾驶员(初级)考试软件