HQL 55 题【已完结】(4)https://developer.aliyun.com/article/1532400
4、登录次数及交易次数统计
需求:分别从登陆明细表(user_login_detail)和配送信息表中用户登录时间和下单时间统计登陆次数和交易次数。
SELECT coalesce(t1.user_id,t0.user_id) user_id, coalesce(t1.login_date,t0.order_date) login_date, nvl(t1.login_count,0) login_count, nvl(t0.order_count,0) order_count FROM ( SELECT user_id, order_date, count(order_date) order_count FROM delivery_info GROUP BY user_id,order_date )t0 RIGHT JOIN ( SELECT user_id, date_format(login_ts,'yyyy-MM-dd') login_date, count(user_id) login_count FROM user_login_detail GROUP BY user_id,date_format(login_ts,'yyyy-MM-dd') )t1 ON t0.user_id=t1.user_id AND t1.login_date=t0.order_date ;
备注:下单的前提的登录,所以是 right join (个人感觉 full join )更合理
4-11
1、查看每件商品的售价涨幅情况
需求:从商品价格变更明细表(sku_price_modify_detail),得到最近一次价格的涨幅情况,并按照涨幅升序排序。
SELECT sku_id, price_change FROM ( SELECT sku_id, change_date, rk, new_price-lead(new_price,1,0) OVER(PARTITION BY sku_id ORDER BY change_date DESC) price_change FROM ( SELECT sku_id, change_date, new_price, row_number() OVER(PARTITION BY sku_id ORDER BY change_date DESC) rk FROM sku_price_modify_detail )t0 WHERE rk<=2 )t1 WHERE rk=1;
2、同期商品售卖分析表
需求:从订单明细表(order_detail)中。求出同一个商品在2021年和2022年中同一个月的售卖情况对比。
SELECT t0.sku_id, nvl(t0.`month`,t1.`month`) `month`, nvl(t1.2020_skusum,0) 2020_skusum, nvl(t0.2021_skusum,0) 2021_skusum FROM ( SELECT sku_id, CAST(date_format(create_date,'MM') AS bigint) `month`, sum(sku_num) 2021_skusum FROM order_detail WHERE date_format(create_date,'yyyy')='2021' GROUP BY sku_id,date_format(create_date,'MM') )t0 FULL JOIN ( SELECT sku_id, CAST(date_format(create_date,'MM') AS bigint) `month`, sum(sku_num) 2020_skusum FROM order_detail WHERE date_format(create_date,'yyyy')='2020' GROUP BY sku_id,date_format(create_date,'MM') )t1 ON t0.sku_id=t1.sku_id AND t0.month=t1.month;
3、国庆期间每个品类的商品的收藏量和购买量
需求:从订单明细表(order_detail)和收藏信息表(favor_info)统计2021国庆期间,每个商品总收藏量和购买量。
SELECT t0.sku_id, nvl(sku_sum,0) sku_sum, nvl(favor_cn,0) favor_cn FROM ( SELECT sku_id, sum(sku_num) sku_sum FROM order_detail WHERE create_date>='2021-10-01' AND create_date<='2021-10-07' GROUP BY sku_id )t0 FULL JOIN ( SELECT sku_id, count(*) favor_cn FROM favor_info WHERE create_date>='2021-10-01' AND create_date<='2021-10-07' GROUP BY sku_id )t1 ON t0.sku_id=t1.sku_id;
4、连续签到领金币数
需求:
- 用户每天签到可以领1金币,并可以累计签到天数,连续签到的第3、7天分别可以额外领2和6金币。
- 每连续签到7天重新累积签到天数。
- 从用户登录明细表中求出每个用户金币总数,并按照金币总数倒序排序。
SELECT coalesce(t1.user_id,t2.user_id) user_id, IF(t2.coins IS NOT NULL,t1.coin+t2.coins,t1.coin) sum_coin_cn FROM -- 查询用户登录次数 ( SELECT user_id, sum(1) coin FROM ( SELECT DISTINCT user_id, date_format(login_ts,'yyyy-MM-dd') login_date FROM user_login_detail )t0 GROUP BY user_id )t1 LEFT JOIN ( -- 查询用户连续登录的次数所能获得的金币 SELECT user_id, IF(count(*)<7,2,8) coins FROM ( SELECT user_id, login_date, row_number() OVER(PARTITION BY user_id ORDER BY login_date) rk FROM ( SELECT DISTINCT user_id, date_format(login_ts,'yyyy-MM-dd') login_date FROM user_login_detail )t )t1 GROUP BY user_id,date_sub(login_date,rk) HAVING count(*)>2 )t2 ON t1.user_id=t2.user_id ;
4-12
1、每个商品销售首年的年份、销售数量和销售金额
需求:从订单明细表(order_detail)统计每个商品销售首年的年份,销售数量和销售总额。
SELECT sku_id, `year`, sum(price*sku_num) order_amount, sum(sku_num) order_num FROM ( SELECT * FROM ( SELECT sku_id, price, create_date, sku_num FROM order_detail )t1 RIGHT JOIN ( -- 销售首年 SELECT sku_id, min(date_format(create_date,'yyyy')) `year` FROM order_detail GROUP BY sku_id )t2 ON t1.sku_id=t2.sku_id AND date_format(create_date,'yyyy')=`year` )t3 GROUP BY sku_id,`year` ;
2、销售订单首购和次购分析
需求:通过商品信息表(sku_info)订单信息表(order_info)订单明细表(order_detail)分析如果有一个用户成功下单两个及两个以上的购买成功的手机订单(购买商品为xiaomi 10,apple 12,小米13)那么输出这个用户的id及第一次成功购买手机的日期和第二次成功购买手机的日期,以及购买手机成功的次数。
SELECT user_id, min(create_date) first_date, max(create_date) last_date, max(rk) cn FROM ( SELECT user_id, sku_num, oi.create_date, row_number() OVER(PARTITION BY user_id ORDER BY oi.create_date) rk FROM order_info oi RIGHT JOIN ( SELECT od.order_id, od.sku_id, od.sku_num, od.create_date,name FROM order_detail od RIGHT JOIN ( SELECT sku_id,name FROM sku_info WHERE name IN ('xiaomi 10','apple 12','xiaomi 13') )t ON t.sku_id=od.sku_id )t1 ON t1.order_id=oi.order_id )t2 GROUP BY user_id ;
3、查询有新注册用户的当天的新用户数量、新用户的第一天留存率
需求:从用户登录明细表(user_login_detail)中首次登录算作当天新增,第二天也登录了算作一日留存
SELECT t2.register_date first_login, t2.register, CAST(t5.retents/t2.register AS DECIMAL(16,2)) retention FROM ( SELECT register_date, count(register_date) register FROM ( SELECT user_id, min(date_format(login_ts,'yyyy-MM-dd')) register_date FROM user_login_detail GROUP BY user_id )t1 GROUP BY register_date )t2 JOIN ( SELECT first_login, sum(retent) retents FROM ( SELECT user_id, login_date first_login, IF(datediff(next_login_date,login_date)=1,1,0) retent FROM ( SELECT user_id, login_date, lead(login_date,1,'9999-12-31') OVER(PARTITION BY user_id ORDER BY login_date) next_login_date FROM ( SELECT user_id, login_date, rk FROM ( SELECT DISTINCT user_id, date_format(login_ts,'yyyy-MM-dd') login_date, row_number() OVER(PARTITION BY user_id ORDER BY date_format(login_ts,'yyyy-MM-dd')) rk FROM user_login_detail )t1 WHERE rk<=2 )t2 )t3 WHERE next_login_date != '9999-12-31' )t4 GROUP BY first_login )t5 ON t5.first_login=register_date;