数据

SQL进阶业务题

2019-10-01  本文已影响0人  周一ing

大多得到的列是需要计算间接得到

1、好评率:利用case when统计出好评数目

统计2018年1月1日到2018年1月31日,用户'小明'提交的母婴类目"花王"品牌的好评率(好评率=“好评”评价量/总评价量):

用户评价详情表:a
字段:id(评价id,主键),create_time(评价创建时间,格式'2017-01-01'), user_name(用户名称),goods_id(商品id,外键) ,
sub_time(评价提交时间,格式'2017-01-01 23:10:32'),sat_name(好评率类型,包含:“好评”、“中评”、“差评”)
商品详情表:b
字段:good_id(商品id,主键),bu_name(商品类目), brand_name(品牌名称)

--mysql版本
select count(case when sat_name='G' then 1 else null end)/count(sat_name) as good_rate
from a, b
where a.goods_id = b.good_id
    and a.user_name = '小明'
    and b.bu_name = '母婴' 
    and b.brand_name = '花王'
    and a.sub_time between '2018-01-01' and '2018-01-31'

2、销售最高的3天,及对应的销售额
小明负责多个品牌的销售业绩,请完成:
(1)请统计小明负责的各个品牌,在2017年销售最高的3天,及对应的销售额。
销售表 a:
字段:logday(日期,主键组),SKU_ID(商品SKU,主键组),sale_amt(销售额)
商品基础信息表 b:
字段:SKU_ID(商品SKU,主键),bu_name(商品类目),brand_name(品牌名称),user_name(运营负责人名称)

链接:https://www.nowcoder.com/questionTerminal/f9979de28d204d0f89a2c027d4a45b3b

--Using sql server
SELECT 
    logday,sale_amt 
FEOM     
    (SELECT 
        ROW_NUMBER() over (partition by brand_name order by sale_amt) as rowId,* 
    FROM a,b 
    WHERE 
        a.SKU_ID=b.SKU_ID and user_name='小明' and a.logday between '2017-01-01' and '2017-12-31'
    )as result 
WHERE result.rowId in (1,2,3)

3、根据相邻条件查询

---Using MYSQL
create view table_joined as (
select * from a,b
where a.SKU_id=b.SKU_id
and user_name='小明'
and year(logday)=2017)

select v1.logday,v1.amt from table_joined v1
where 3<(select count(*) from table_joined v2
where v1.brand_name=v2.brand_name
and v1.sale_amt<v2.sale_amt)
order by logday,sale_amt

SELECT DISTINCT S1.*
FROM stadium AS S1,stadium AS S2,stadium AS S3
WHERE S1.people>=100 AND S2.people>=100 AND S3.people>=100 AND (
    S1.id +1 = S2.id AND S1.id+2=S3.id OR
    S1.id +1 = S2.id AND S1.id-1=S3.id OR
    S1.id -1 = S2.id AND S1.id-2=S3.id
)
ORDER BY S1.id
select creat_time,count(distinct user_id) lead(type,1) over () type1 
from activity where type='A' and type1 = 'B' group by creat_time

4、新增留存问题

select a.sign_time, count(a.user_id) number
    from
(select user_id, min(time) sign_time from login group by user_id) a group by a.sign_time
SELECT
    --根据新增表newUsertable和留存表liucuntable得到每个注册日的次日留存率和30日留存率
    liucuntable.sign_time,
    newUsertable.newUser,
    round(cast( liucuntable.day_2 as float )/newUsertable.newUser,2) as day2_rate,
    round(cast( liucuntable.day_30 as float )/newUsertable.newUser,2) as day30_rate
FROM
    --liucuntable是根据ab得到每个注册日的第二天回访人数,第30天回访人数
    (SELECT sign_time,
        sum(case when byday=1 then 1 else 0 end) as day_2,
        sum(case when byday=29 then 1 else 0 end) as day_30,
    FROM
        --evetable是每天每个用户的登录时间,取当天该用户最早的登录时间,signtable是每个用户的注册时间 ,
        --ab得到每个新增日的每个新增用户的登录时间-注册时间      
        (SELECT 
            evetable.user_id,signtable.sign_time,evetable.eve_time,
            DATEDIFF(day,signtable.sign_time,evetable.eve_time) as byday 
        FROM
            --DATEPART(dy,time)取time在1-365的天数,这里可能会有错误,如果不同年同一天
            (SELECT user_id, min(time) eve_time FROM login group by user_id,to_Date(dy,time)) evetable,
            (SELECT user_id, min(time) sign_time FROM login group by user_id) signtable
        WHERE evetable.user_id = signtable.user_id) ab group by sign_time) liucuntable,
    (SELECT a.sign_time, count(distinct a.user_id) newUser
        FROM
        (SELECT user_id, min(time) sign_time FROM login group by user_id) a 
    group by a.sign_time) newUsertable
WHERE  liucuntable.sign_time = newUsertable.sign_time 

统计回购率和复购率(回购率是指3月份购买的用户下个月又下单了,复购率是在一段时间内两次及以上购买)

 --求3月份复购率,这里假设年份一致
 --先得到每个人的购买次数
 --统计所有人数,以及复购的人数量
 select count(ct)/count(if(ct>1,1,null)) from   
    (select userID,count(userID) as ct from orders
    where month(paidtime)=3
    group by userID) t
    
 --求回购率,如果仅仅是说3月的回购率,则可以简单的将4月份购买的用户在3月份也购买筛选出来
 select count(*) from orders 
 where userID in (子查询,算出3月份的userID) and month(paidtime)=4
 group by userID
 
 --求每个月的回购率,
--得到每个用户在每个月是否有消费记录
 --利用表的左连接,得到每个用户在不同月份的消费记录
 --每个用户后一个消费记录的月份-前一个消费记录=1,匹配出每个用户连续两个月份都有消费的记录,
 --得到每个月份,对应的消费人数,以及回购人数
 select t1.m,count(t1.m),count(t2.m) from
     (select userID,date_formate(paidtime,'%Y-%m-01') as m
     from orders
     group by userID,date_formate(paidtime,'%Y-%m-01')) t1,
 left join    
    (select userID,date_formate(paidtime,'%Y-%m-01') as m
    from orders
    group by userID,date_formate(paidtime,'%Y-%m-01')) t2
 on t1.userID = t2.userID and t1.m=date_sub(t2.m,interval 1 month)
 group by t1.m
--筛选出use表中性别列不为空的数据
--和order表内连接,根据用户和性别分组,得到每个用户的消费频次
--根据性别分组,得到男女的平均消费数目
select sex,avg(ct)
    (select t.userID,sex,count(1) as ct from orders,
        (select * from user
        where sex<>'') t
    where orders.userID = t.userID
    group by userID,sex) t2
group by sex   
--先提取出多次消费的用户
--计算每个用户最后一次消费时间与第一次时间间隔
 select userID,date_diff(max(paidtime),min(paidtime)) from orders 
 group by userID having count(1)>1
--先将出生日换算成年龄,并分割成年龄段,并剔除脏数据
--与orders内连接,并按年龄段,TIPS:group by带上age,是为了查询age不用再嵌套
select age,avg(ct)
    (select o.userID,o.age,count(o.userID) as ct from orders o,
    inner join
        (select userID,cell((year(now())-year(birth))/10) from users
        where birth > '1901-00-00') t
    on o.userID = t.userID
    group by o.userID,age) t2
group by age    
上一篇下一篇

猜你喜欢

热点阅读