金九银十的招聘季接近尾声,各位毕业生在一番腥风血雨的竞争中找寻着自己满意的工作,想想当时起早贪黑赶趟面试也是一把心酸累。随着互联网寒冬的到来,工作越发的难找,大家躲过了面试的坑却还是躲不过企业家优化组织结构的坑(裁员甚至裁掉应届生),所以各位找工作的娃儿在选择的时候一定在睁大双眼选择对的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分析函数可以快速实现这个过程,简便快捷。


数据分析师的面试问题 数据分析师 面试题_分析函数_02

eg:

数据分析师的面试问题 数据分析师 面试题_分析函数_02

     例如有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时间列的格式转化为年-月-日的格式;

 

数据分析师的面试问题 数据分析师 面试题_SQL_04