HQL 55 题【已完结】(5)

简介: HQL 55 题【已完结】

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;
相关文章
|
5月前
|
SQL HIVE
|
2月前
|
SQL 数据库 C++
SQL 执行顺序,通俗易懂!
在数据库的世界里,SQL(Structured Query Language)是我们与数据对话的桥梁。编写一个高效的SQL查询,不仅要求我们理解数据库的结构和数据模型,还需要掌握SQL的执行顺序。但往往,这个顺序与我们在编写SQL时书写的顺序并不一致,这常常让初学者感到困惑。今天,我们就来用通俗易懂的方式,揭开SQL执行顺序的神秘面纱。
99 2
|
5月前
|
SQL Java 数据库连接
MyBatis SQL 批量更新(代码➕案例)
MyBatis SQL 批量更新(代码➕案例)
865 0
|
SQL Python
python技术面试题(七)--SQL语句
python技术面试题(七)--SQL语句
|
SQL 数据库
图解 SQL 执行顺序,通俗易懂!
图解 SQL 执行顺序,通俗易懂!
659 0
|
SQL XML 缓存
面试官问你MyBatis SQL是如何执行的?把这篇文章甩给他(一)
MyBatis 是第一个支持自定义 SQL、存储过程和高级映射的类持久框架。MyBatis 消除了大部分 JDBC 的样板代码、手动设置参数以及检索结果。MyBatis 能够支持简单的 XML 和注解配置规则。使 Map 接口和 POJO 类映射到数据库字段和记录。
169 0
面试官问你MyBatis SQL是如何执行的?把这篇文章甩给他(一)
多表查询 SQL21用户题目回答情况(三种写法)
多表查询 SQL21用户题目回答情况(三种写法)
158 0
多表查询 SQL21用户题目回答情况(三种写法)