这道SQL笔试题你会怎么写

  最近面试了一些Senior BI的候选人,行业经验三年到七年不等,起初觉得这个Level的无需准备笔试题,碍于领导执念,就在真实项目中提取5道SQL题目,这里仅单说其中一道难度中等偏下的题目,抛开面试不谈,单看笔试的话几轮下来答题情况并不理想,至今没有发现有人能写出逻辑滴水不漏又性能最大化的脚本,难点的题目甚至还有交白卷的情况,如果看官觉得这仅仅是茴香豆的茴几种写法的问题就飘过吧,我想通过题目考察的并非只是SQL的熟练程度,相对而言更看重候选人对数据的敏感程度,以及脚本性能的优化能力,往深了说就是要了解数据库存储引擎及查询优化器的工作原理,这是一个合格的BI从业者应有的基本素质。

  题目是这样的,有一张ER图描述数据结构,这里就不贴图了,简单文字描述如下,劳烦看官各种脑补主外键关系:

  一张会员表(account),字段有会员id(account_id), 会员卡号(account_num)。。。

  一张交易订单表(trans),字段有会员id(account_id),交易时间(trans_time),交易金额(sales)。。。

  要求查询出所有首笔订单金额超过1000的会员卡号及其首笔订单金额,

  注:

  1. 首笔订单指的是每个会员交易时间最小的一笔订单

  2. 会员表有一千万笔记录

  3. 如果会员没有任何订单或者首笔订单金额不足1000,则首笔订单金额返回0。

  下面提供三例典型的答题脚本供参考,候选人BI经验分别是三年,四年,六年,脚本笔录风格太过任性,因为题目没有约束DB产品,所以有使用各种DB私有函数的,有使用join的旧式写法的,甚至还有使用CTE的,状况百出,为照顾看官心情,在尊重原著本意的原则下梳理后的TSQL脚本如下:

  A

  select a.account_number, t.sales

  from Account a

  join

  (

  select account_id, sales, min(trans_time)

  from trans

  group by trans_id

  having sum(sales)>1000

  ) t on a.account_id=t.account_id

  B

  select a.account_number, t.sales, rank() over(partition by a.account_id order by t.trans_time) rn

  from account a

  join trans t on a.account_id=t.account_id

  where rn=1 and t.sales>1000

  group by a.account_number,t.trans_time

  C

  Select a.account_number, t.sales

  From Account a

  left join

  (

  Select account_id,sales,row_number() over(order by trans_time) rn

  From Trans

  ) t on a.account_id=t.account_id

  where t.rn=1 and t.sales>1000

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值