金九银十的招聘季接近尾声,各位毕业生在一番腥风血雨的竞争中找寻着自己满意的工作,想想当时起早贪黑赶趟面试也是一把心酸累。随着互联网寒冬的到来,工作越发的难找,大家躲过了面试的坑却还是躲不过企业家优化组织结构的坑(裁员甚至裁掉应届生),所以各位找工作的娃儿在选择的时候一定在睁大双眼选择对的boss!!!
小编在找工作的过程中把各个大厂的面试经记录下来,一方面是为了之后的面试做准备,另一方面想要分享给更多的同学,尤其是学弟学妹们。、
热乎乎的面经来了!!!
数据分析师的面试很多避免不了对于数据库SQL知识的考察,这次推文主要做的是关于面试中关于SQL的一些经典的手撕代码题。
本文以下列表为问题背景,存在的表格以及列选项如下:
1.客户订单表ord
包含的列选项包含
用户ID:user_id
下单时间:create_time1
订单ID:ord_id
产品ID:product_id)
2.商品促销活动表act
用户ID:user_id
用户参与活动的时间:create_time2
指的是用户报名活动的时间,一个用户只能报名一次
活动ID:act_id
3.客户访问表log
用户ID:user_id
访问时间:log_time
一个用户可能存在多次访问,包括活动推广之前和活动推广之后都会访问商品
0 1
创建新表
创建新的表,包含以下内容:
每日APP的访问人数以及用户的订单数量的分布情况
create table as log_app
select count(distinct user_id)
from log
group by log_time;
create table as user_ord
select user_id,count(ord_id)
from ord
group by user_id;
参加活动后的用户的订单次数、订单金额;
Select user_id,count(create_time),sum(ord_amt)
from ord o
join act a
on a.user_id = o.user_id
where o.create_time>=a.ceate_time
group by user_id;
在SQL考察中,select 语句的基本语法结构要熟悉掌握,具体包括group by/order by/where/join的用法和sum/count等聚合函数的用法。
02 over函数
查看每日新增客户,利用 first_value( ) over( )函数可以很好地实现这个功能。
select distinct user_id,
first_value(log_time)
over (partition by user_id order by log_time)
as new_first_time
from log;
除了first_value()over()函数,此外还有
last_value() over()、
rank()over()
row_number()over()
sum()over()
count()over()
max()over()
lag()over()
lead()over()
这些函数都会在面试中考察到,下面的例子便于大家来理解各个函数的用法和其实现的功能;
rank()over()是排序函数,用于对结果进行排名,例如根据学生的成绩score对不同的班级class的学生进行排名,得到排名列rank,具体实现过程如下:
rank() over(partition by class order by score) as rank;
sum() over()是累积加和函数;
Lag和Lead分析函数可以在同一次查询中取出同一字段的前N行的数据(Lag)和后N行的数据(Lead)作为独立的列,例如想要得到一周后或者一个月之前或者之后的数据,或者推广活动前后一周的数据进行对比分析的时候利用Lag和Lead分析函数可以快速实现这个过程,简便快捷。
eg:
例如有A/B/C三种商品,求出先购买A产品后购买B产品且AB产品相连的客户数量,包含的列如下:
user_id
A_create_time
B_create_time
C_create_time
实现的方法多种多样,首先我们利用自连接的方法实现:
自连接方法连接成一张大表,条件判断A的时间先于B,C的时间小于A或者晚于B,满足条件。
Create table as a
Select * from ord
Where product_id = A;
Create table as b
Select * from ord
Where product_id = B;
Create table as c
Select * from ord
Where product_id = C;
Select a. user_id ,a.create_time,
b.create_time,
c.create_time,
(case when c.createtime is Null
and
a.createtime < b.createtime then 1
when c.createtime is not null
and
a.createtime
and
b.createtime
as d
From
(Select * from ord o
Where o.product_name =A)a
Join
(Select * from ord o
Where o.product_name =B)b
On
a. user_id = b.user_id
Join
(Select * from ord o
Where o.product_name =C)c
On
a.user_id = c.user_id
第二种方法,利用lead()over()函数来实现,难点是A操作后是B,AB必须相连,这个最方便的就是用开窗数lead() over()轻松实现.
select user_id ,
(case when product_id = A
and
product_next = B then 1 else 0) as d
from
(select *,
lead(product_name,1) over(opartition by user_id) as product_next
from ord o)
where d = 1;
03 日期函数
SQL中的日期函数主要包括:
dateadd函数用于在日期中添加或减去指定的时间间隔。例如计算当前时间往后一天的时刻以及往前1天的时刻时间即可使用DateAdd()函数来操作
DateAdd()函数的格式为:
DATEADD(datepart,number,date);
datesub函数从日期减去指定的时间间隔,用法类似于 dateadd函数;
datediff时间差函数
datediff(day,t1,t2)即计算t1,t2时间列对应的时间长度,并以天的时间长度来计算;
date_format时间格式转换函数
date_format(log_time,'%y%m%d')即将log_time时间列的格式转化为年-月-日的格式;