HQL 55 题【已完结】(4)

简介: HQL 55 题【已完结】

HQL 55 题【已完结】(3)https://developer.aliyun.com/article/1532399

7、男性和女性每日的购物总金额统计

需求:从订单信息表(order_info)和用户信息表(user_info)中,分别统计每天男性和女性用户的订单总金额,如果当天男性或者女性没有购物,则统计结果为0。

SELECT create_date,
     sum(IF(gender='男',total_amount,0)) total_amount_male,
       sum(IF(gender='女',total_amount,0)) total_amount_female
FROM
(
  SELECT oi.user_id,gender,total_amount,create_date
    FROM order_info oi 
    LEFT JOIN user_info ui ON oi.user_id=ui.user_id
)t1
GROUP BY create_date;

或者

SELECT create_date,  
       SUM(CASE WHEN gender = '男' THEN total_amount ELSE 0 END) AS total_amount_male,  
       SUM(CASE WHEN gender = '女' THEN total_amount ELSE 0 END) AS total_amount_female  
FROM (  
    SELECT oi.user_id, ui.gender, oi.total_amount, oi.create_date  
    FROM order_info oi   
    LEFT JOIN user_info ui ON oi.user_id = ui.user_id  
) t1  
GROUP BY create_date;

3-27

1、购买过商品1和商品2但是没有购买商品3的顾客

SELECT user_id
FROM
(
  SELECT user_id,
     sum(IF(sku_id IN (1,2),1,0)) sum_num,
       MAX(CASE WHEN sku_id = 3 THEN 1 ELSE 0 END) AS has_sku_3
    FROM
    (
        SELECT DISTINCT od.sku_id,oi.user_id
        FROM order_detail od
        JOIN order_info oi ON od.order_id=oi.order_id
    )t1
    GROUP BY user_id
)t2
WHERE has_sku_3=0 AND sum_num=2;

判断是否包含 sku_id = 3 的记录不能使用功能 if,这里用的是 MAX(CASE WHEN) 新的思路,需要好好记住!

2、订单金额趋势分析

SELECT
  create_date,
    cast(sum(total_amount) over(partition by ds rows between 2 preceding and current ROW) as decimal(16,2)) total_3d,
    cast(avg(total_amount) over(partition by ds rows between 2 preceding and current row) as decimal(16,2)) avg_3d
FROM
(
  SELECT
  t1.create_date,
    total_amount,
    date_sub(create_date,row_number() over(order by create_date)) ds
FROM
(
  SELECT
  create_date,
    sum(total_amount) total_amount
FROM order_info
group by create_date
  )t1
)t2;

3-29

1、统计每日商品1和商品2销量的差值

SELECT coalesce(t1.create_date,t2.create_date) create_date,
     IF(t1.sku_num is null,0,t1.sku_num)-IF(t2.sku_num is null,0,t2.sku_num) diff
FROM
(
SELECT create_date,
       sum(sku_num) sku_num
FROM order_detail
WHERE sku_id='1'
GROUP BY create_date
)t1
FULL OUTER JOIN
(
SELECT create_date,
       sum(sku_num) sku_num
FROM order_detail
WHERE sku_id='2'
GROUP BY create_date
)t2
ON t1.create_date=t2.create_date;

2、查询出每个用户的最近三笔订单

SELECT user_id,
     order_id,
       create_date
FROM
(
    SELECT user_id,
           order_id,
           create_date,
           dense_rank() OVER(PARTITION BY user_id ORDER BY create_date DESC) rk
    FROM order_info
)t1
WHERE rk<=3;

3、查询每个用户登录日期的最大空档期

SELECT user_id,
     max(diff) max_diff
FROM
(
  SELECT user_id,
     datediff(date_format(lead(login_ts,1,'2021-10-10') OVER(PARTITION BY user_id ORDER BY login_ts),'yyyy-MM-dd'),date_format(login_ts,'yyyy-MM-dd')) diff
    FROM user_login_detail
)t1
GROUP BY user_id;

4、查询统一时刻多地登录的用户

SELECT DISTINCT user_id
FROM
(
  SELECT user_id,
     if(ip != next_ip AND login_ts <= next_login_ts,1,0) status
    FROM
    (
        SELECT user_id,
               ip_address ip,
               login_ts,
               lead(ip_address,1) OVER(PARTITION BY user_id ORDER BY login_ts) next_ip,
               lead(login_ts,1) OVER(PARTITION BY user_id ORDER BY login_ts) next_login_ts
        FROM user_login_detail
    )t1
)t2
WHERE t2.status=1;

5、各品类销量前三的所有商品

SELECT sku_id,category_id
FROM
(
    SELECT  t1.sku_id,
            sum_num,
            si.category_id,
            row_number() OVER(PARTITION BY si.category_id ORDER BY sum_num DESC) rk
    FROM
    (
        SELECT sku_id,sum(sku_num) sum_num FROM order_detail GROUP BY sku_id
    )t1
    JOIN sku_info si ON si.sku_id=t1.sku_id
)t2 WHERE rk<=3;

4-9

网站崩了几天,所以没更。

1、各品类中的商品价格中位数

需求:从商品信息表(sku_info)求出各分类商品价格的中位数,如果一个分类下的商品个数为偶数则输出中间两个值的平均值,如果是奇数,则输出中间数即可。

思路1

SELECT  category_id,
    CAST(sum(price)/count(*) AS DECIMAL(16,2)) medprice
FROM
(
    SELECT  category_id,
            price,
            rk,
            max(rk) OVER(PARTITION BY category_id) max_rk
    FROM
    (
        SELECT  category_id,
            price,
                row_number() OVER(PARTITION BY category_id ORDER BY price) rk
        FROM sku_info
    )t1
)t2
WHERE rk IN (ceil((max_rk+1)/2),floor((max_rk+1)/2))
GROUP BY category_id;

思路2

select
    category_id,
    cast(avg(price) as DECIMAL(10,2)) medprice
from (
    select
        *,
        ceil(count / 2) mid,
        `if`(count % 2 = 0, 1, 0) flag
    from (
        select
            sku_id,
            category_id,
            price,
            row_number() over (partition by category_id order by price) rn,
            count(1) over (partition by category_id) count
        from sku_info
    )t
)t1 where rn = mid or rn = mid + flag
group by category_id;

4-10

1、找出销售额连续3天超过100的商品

需求:从订单详情表(order_detail)中找出销售额连续3天超过100的商品。

SELECT DISTINCT sku_id
FROM
(
    SELECT  sku_id,
            create_date,
            row_number() OVER(PARTITION BY sku_id ORDER BY create_date) rk
    FROM 
    GROUP BY sku_id,create_date
    HAVING sum(price*sku_num)>100
)t1
GROUP BY sku_id,date_sub(create_date,rk)
HAVING count(*)>2;

子表 t1 中的 GROUP BY sku_id,create_date 的作用是对一天多个订单进行去重。

2、查询所有用户的连续登录两天及以上的日期区间

需求:从登录明细表(user_login_detail)中查询出,所有用户的连续登录两天及以上的日期区间,以登录时间(login_ts)为准。

SELECT  user_id,
    min(login_date) start_date,
        max(login_date) end_date
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
    )t1
)t2
GROUP BY user_id,date_sub(login_date,rk)
HAVING count(*)>1;

3、求出商品连续售卖的时间区间

需求:从订单详情表(order_detail)中,求出商品连续售卖的时间区间(1天也算连续)

SELECT  sku_id,
    min(create_date) start_date,
        max(create_date) end_date
FROM
(
    SELECT  sku_id,
            create_date,
            row_number() OVER(PARTITION BY sku_id ORDER BY create_date) rk
    FROM 
    (
        SELECT DISTINCT sku_id,create_date FROM order_detail
    )t1
)t2
GROUP BY sku_id,date_sub(create_date,rk)
HAVING count(*)>0;

HQL 55 题【已完结】(5)https://developer.aliyun.com/article/1532401

相关文章
|
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用户题目回答情况(三种写法)