一、提要

作为一名数据工作人员,SQL是日常工作中最常用的数据提取&简单预处理语言。因为其使用的广泛性和易学程度也被其他岗位比如产品经理、研发广泛学习使用,本篇文章主要结合经典面试题,给出通过数据开发面试的SQL方法与实战。以下题目均来与笔者经历&网上分享的中高难度SQL题。

二、解题思路

  • 简单——会考察一些group by & limit之类的用法,或者平时用的不多的函数比如rand()类;会涉及到一些表之间的关联

  • 中等——会考察一些窗口函数的基本用法;会有表之间的关联,相对tricky的地方在于会有一些自关联的使用

  • 困难——会有中位数或者更加复杂的取数概念,可能要求按照某特定要求生成列;一般这种题建中间表会解得清晰些

三、SQL真题

第一题

  • order订单表,字段为:goods_id, amount ;

  • pv 浏览表,字段为:goods_id,uid;

  • goods按照总销售金额排序,分成top10,top10~top20,其他三组

求每组商品的浏览用户数(同组内同一用户只能算一次)


create table if not exists test.nil_goods_category asselect goods_id,case when nn<= 10 then 'top10'      when nn<= 20 then 'top10~top20'      else 'other' end as goods_groupfrom(    select goods_id    ,row_number() over(partition by goods_id order by sale_sum desc) as nn    from    (        select goods_id,sum(amount) as sale_sum        from order        group by 1    ) aa) bb;select b.goods_group,count(distinct a.uid) as numfrom pv a left join test.nil_goods_category b on a.goods_id = b.goods_idgroup by 1;

第二题

商品活动表 goods_event,g_id(有可能重复),t1(开始时间),t2(结束时间)

给定时间段(t3,t4),求在时间段内做活动的商品数


1.select count(distinct g_id) as event_goods_numfrom goods_eventwhere (t1<=t4 and t1>=t3) or (t2>=t3 and t2<=t4)

2.select count(distinct g_id) as event_goods_numfrom goods_eventwhere (t1<=t4 and t1>=t3) union all

第三题

商品活动流水表,表名为event,字段:goods_id, time;

求参加活动次数最多的商品的最近一次参加活动的时间


select a.goods_id,a.timefrom event a inner join(    select goods_id,count(*)    from event    group by gooods_id    order by count(*) desc    limit 1) bon a.goods_id = b.goods_idorder by a.goods_id,a.time desc

第四题

用户登录的log数据,划定session,同一个用户一个小时之内的登录算一个session;

生成session列


drop table if exists koo.nil_temp0222_a2;create table if not exists koo.nil_temp0222_a2 asselect *    ,row_number() over(partition by userid order by inserttime) as nn1from(    select a.*    ,b.inserttime as inserttime_aftr    ,datediff(b.inserttime,a.inserttime) as session_diff  from  (    select userid,inserttime      ,row_number() over(partition by userid order by inserttime asc) nn    from koo.nil_temp0222    where userid = 1900000169  ) a    left join  (     select userid,inserttime      ,row_number() over(partition by userid order by inserttime asc) nn    from koo.nil_temp0222    where userid = 1900000169  ) b  on a.userid =  b.userid and a.nn = b.nn-1) aawhere session_diff >10 or nn = 1order by userid,inserttime;

drop table if exists koo.nil_temp0222_a2_1;create table if not exists koo.nil_temp0222_a2_1 asselect a.*,case when b.nn is null then a.nn+3 else b.nn end as nn_endfrom koo.nil_temp0222_a2 a left join koo.nil_temp0222_a2 b on a.userid = b.userid and a.nn1 = b.nn1 - 1;

select a.*,b.nn1 as session_idfrom(  select userid,inserttime    ,row_number() over(partition by userid order by inserttime asc) nn  from koo.nil_temp0222  where userid = 1900000169) aleft join koo.nil_temp0222_a2_1 b on a.userid = b.useridand a.nn>=b.nnand a.nn<b.nn_end

第五题

订单表,字段有订单编号和时间;

取每月最后一天的最后三笔订单


select *from(  select *  ,rank() over(partition by mm order by dd desc) as nn1  ,row_number() over(partition by mm,dd order by inserttime desc) as nn2  from  (select cast(right(to_date(inserttime),2) as int) as dd,month(inserttime) as mm,userid,inserttime  from koo.nil_temp0222) aa ) bb where nn1 = 1 and nn2<=3;

第六题

数据库表Tourists,记录了某个景点7月份每天来访游客的数量如下:

id date visits 1 2017-07-01 100 …… 非常巧,id字段刚好等于日期里面的几号。

现在请筛选出连续三天都有大于100天的日期。

上面例子的输出为:date 2017-07-01 ……


select a.*,b.num as num2,c.num as num3from table  a left join table bon a.userid = b.useridand a.dt = date_add(b.dt,-1)left join table con a.userid = c.useridand a.dt = date_add(c.dt,-2)where b.num>100and a.num>100and c.num>100

第七题

现有A表,有21个列,第一列id,剩余列为特征字段,列名从d1-d20,共10W条数据!

另外一个表B称为模式表,和A表结构一样,共5W条数据

请找到A表中的特征符合B表中模式的数据,并记录下相对应的id

有两种情况满足要求:

  • 每个特征列都完全匹配的情况下

  • 最多有一个特征列不匹配,其他19个特征列都完全匹配,但哪个列不匹配未知


1.select aa.*from(  select *,concat(d1,d2,d3……d20) as mmd  from table) aa left join(  select id,concat(d1,d2,d3……d20) as mmd  from table) bb on aa.id = bb.idand aa.mmd = bb.mmd

2.select a.*,sum(d1_jp,d2_jp……,d20_jp) as same_judgefrom(  select a.*  ,case when a.d1 = b.d1 then 1 else 0 end as d1_jp  ,case when a.d2 = b.d2 then 1 else 0 end as d2_jp  ,case when a.d3 = b.d3 then 1 else 0 end as d3_jp  ,case when a.d4 = b.d4 then 1 else 0 end as d4_jp  ,case when a.d5 = b.d5 then 1 else 0 end as d5_jp  ,case when a.d6 = b.d6 then 1 else 0 end as d6_jp  ,case when a.d7 = b.d7 then 1 else 0 end as d7_jp  ,case when a.d8 = b.d8 then 1 else 0 end as d8_jp  ,case when a.d9 = b.d9 then 1 else 0 end as d9_jp  ,case when a.d10 = b.d10 then 1 else 0 end as d10_jp  ,case when a.d20 = b.d20 then 1 else 0 end as d20_jp  ,case when a.d11 = b.d11 then 1 else 0 end as d11_jp  ,case when a.d12 = b.d12 then 1 else 0 end as d12_jp  ,case when a.d13 = b.d13 then 1 else 0 end as d13_jp  ,case when a.d14 = b.d14 then 1 else 0 end as d14_jp  ,case when a.d15 = b.d15 then 1 else 0 end as d15_jp  ,case when a.d16 = b.d16 then 1 else 0 end as d16_jp  ,case when a.d17 = b.d17 then 1 else 0 end as d17_jp  ,case when a.d18 = b.d18 then 1 else 0 end as d18_jp  ,case when a.d19 = b.d19 then 1 else 0 end as d19_jp  from table a  left join table b  on a.id = b.id ) aawhere sum(d1_jp,d2_jp……,d20_jp) = 19

第八题

我们把用户对商品的评分用稀疏向量表示,保存在数据库表t里面:

  • t的字段有:uid,goods_id,star。uid是用户id

  • goodsid是商品id

  • star是用户对该商品的评分,值为1-5

现在我们想要计算向量两两之间的内积,内积在这里的语义为:

对于两个不同的用户,如果他们都对同样的一批商品打了分,那么对于这里面的每个人的分数乘起来,并对这些乘积求和。

例子,数据库表里有以下的数据:

U0 g0 2
U0 g1 4
U1 g0 3
U1 g1 1

计算后的结果为:

U0 U1 23+41=10 ……


select aa.uid1,aa.uid2,sum(star_multi) as resultfrom(  select a.uid as uid1  ,b.uid as uid2  ,a.goods_id  ,a.star * b.star as star_multi  from t a  left join t b  on a.goods_id = b.goods_id  and a.udi<>b.uid  ) aa group by 1,2


select uid1,uid2,sum(multiply) as resultfrom(select t.uid as uid1, t.uid as uid2, goods_id,a.star*star as multiplyfrom a left join b on a.goods_id = goods_idand a.uid<>uid) aagroup by goods

第九题

给出一堆数和频数的表格,统计这一堆数中位数


select a.*,b.s_mid_n,c.l_mid_n,avg(b.s_mid_n,c.l_mid_n)from(  select  case when mod(count(*),2) = 0 then count(*)/2 else (count(*)+1)/2 end as s_mid  ,case when mod(count(*),2) = 0 then count(*)/2+1 else (count(*)+1)/2 end as l_mid    from table) a left join(  select id,num,row_number() over(partition by id order by num asc) nn  from table) b on a.s_mid = b.nnleft join(  select id,num,row_number() over(partition by id order by num asc) nn  from table) c  on a.l_mid = c.nn

第十题

表order有三个字段,店铺ID,订单时间,订单金额

查询一个月内每周都有销量的店铺


select distinct credit_levelfrom(  select credit_level,count(distinct nn) as number  from  (    select userid,credit_level,inserttime,month(inserttime) as mm    ,weekofyear(inserttime) as week    ,dense_rank() over(partition by credit_level,month(inserttime) order by weekofyear(inserttime) asc) as nn    from koo.nil_temp0222    where substring(inserttime,1,7) = '2019-12'    order by credit_level ,inserttime    ) aa  group by 1  ) bbwhere number = (select count(distinct weekofyear(inserttime))from koo.nil_temp0222 where substring(inserttime,1,7) = '2019-12')

经典SQL面试10题(附答案)相关推荐

  1. 收藏微软面试智力题 (附答案)

    A.逻辑推理 1.你让工人为你工作7天,给工人的回报是一根金条.金条平分成相连的7段 ,你必须在每天结束时给他们一段金条,如果只许你两次把金条弄断,你如何给你 的工人付费?   2.请把一盒蛋糕切成8 ...

  2. 微软面试智力题(附答案)

    转自: http://www.blogjava.net/wenhan-uk/archive/2007/08/17/137703.html 收藏微软面试智力题 (附答案) A.逻辑推理 1.你让工人为你 ...

  3. 面试智力题 (附答案)

    A.逻辑推理    1.你让工人为你工作7天,给工人的回报是一根金条.金条平分成相连的7段 ,你必须在每天结束时给他们一段金条,如果只许你两次把金条弄断,你如何给你的工人付费?  2.请把一盒蛋糕切成 ...

  4. JAVA经典算法面试40题及答案

    By Lee - Last updated: 星期日, 三月 9, 2014 现在是3月份,也是每年开年企业公司招聘的高峰期,同时有许多的朋友也出来找工作.现在的招聘他们有时会给你出一套面试题或者智力 ...

  5. Java经典基础与高级面试36题和答案

    在Java面试的首轮,经常会问很多关于Java面试基础以及高级的问题,今天收集相关Java面试36题和答案分享出来. 1."static"关键字是什么意思?Java中是否可以覆盖( ...

  6. 微软等数据结构+算法面试100题全部答案集锦

    微软等数据结构+算法面试100题全部答案集锦 作者:July.阿财. 时间:二零一一年十月十三日. 引言 无私分享造就开源的辉煌. 今是二零一一年十月十三日,明日14日即是本人刚好开博一周年.在一周年 ...

  7. 微软等数据结构+算法面试100题全部答案完整亮相

    重磅分享:微软等数据结构+算法面试100题全部答案完整亮相 来源: 王永刚的日志 本文转载自CSDN大牛的一篇博客:http://blog.csdn.net/v_july_v/article/deta ...

  8. (转)微软等数据结构+算法面试100题全部答案集锦

    微软等数据结构+算法面试100题全部答案集锦 作者:July.阿财. 时间:二零一一年十月十三日. 引言 无私分享造就开源的辉煌. 今是二零一一年十月十三日,明日14日即是本人刚好开博一周年.在一周年 ...

  9. 微软等数据结构+算法面试100题全部答案集锦 复制过来比较乱

    亲,"社区之星"已经一周岁了!        WebApp实时开源框架Clouda---认识心得      Tag功能介绍-我们为什么打Tag      订阅CSDN社区周刊,及时 ...

  10. 史上最强多线程面试44题和答案:线程锁+线程池+线程同步等

    最全BAT必考题答案系列 最全MySQL面试60题和答案 史上最全Spring面试71题与答案 史上最全Redis面试49题(含答案):哨兵+复制+事务+集群+持久化等 分布式缓存Redis+Memc ...

最新文章

  1. 蓝鸥Unity开发基础——Switch语句学习笔记
  2. python语言中文社区-python解决中文
  3. UA MATH565C 随机微分方程V Markov Family的算子
  4. 【Matlab】怎么判断两个字符串相等?
  5. Leet Code OJ 118. Pascal's Triangle [Difficulty: Easy]
  6. 诊断日志知多少 | DiagnosticSource 在.NET上的应用
  7. Android获取当前网络状态
  8. SAP License:SAP的联产品和副产品
  9. Android_WakeLock使用
  10. C++ 好的博客??
  11. QT QComBox详细用法 自定义QComboBox控件
  12. cad计算机绘图实操视频,cad工程制图教程视频
  13. IC前端设计使用的EDA软件
  14. 创建第一个Android app项目
  15. mac配置adb环境变量
  16. java wps linux 安装_安装wps for linux无法启动
  17. easyExcel 导出 excel 自定义表头
  18. excel不能复制粘贴怎么回事
  19. HDU 6318 Swaps and inversions
  20. 小米商城项目实战(一)

热门文章

  1. 10大编程语言之父,你知道几个?
  2. 人工智能技术发展综述
  3. 最佳的46+14款免费软件
  4. 2021年零基础学Delphi 11开发极简教程
  5. VC2008配置设置(转)
  6. 鲸云效解读A/B测试,get这一篇就够了
  7. Idea导入jar包的两种方法
  8. windows10使用mklink命令给C盘软件搬家
  9. opencv:image-imageData+image-widthStep*i)[j]表达式含义
  10. 网站定时监控平台有哪些 7款好用的实时监控网站工具