温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何使用SQL窗口函数进行商务数据分析

发布时间:2021-12-16 13:54:56 阅读:155 作者:iii 栏目:大数据

这篇文章主要讲解了“如何使用SQL窗口函数进行商务数据分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用SQL窗口函数进行商务数据分析”吧!

数据准备

本文主要分析只涉及一张订单表orders,操作过程在Hive中完成,具体数据如下:

-- 建表CREATE TABLE orders(    order_id int,    customer_id string,    city string,    add_time string,    amount decimal(10,2));-- 准备数据                              INSERT INTO orders VALUES(1,"A","上海","2020-01-01 00:00:00.000000",200),(2,"B","上海","2020-01-05 00:00:00.000000",250),(3,"C","北京","2020-01-12 00:00:00.000000",200),(4,"A","上海","2020-02-04 00:00:00.000000",400),(5,"D","上海","2020-02-05 00:00:00.000000",250),(5,"D","上海","2020-02-05 12:00:00.000000",300),(6,"C","北京","2020-02-19 00:00:00.000000",300),(7,"A","上海","2020-03-01 00:00:00.000000",150),(8,"E","北京","2020-03-05 00:00:00.000000",500),(9,"F","上海","2020-03-09 00:00:00.000000",250),(10,"B","上海","2020-03-21 00:00:00.000000",600);
   

需求1:收入增长

在业务方面,第m1个月的收入增长计算如下:100 *(m1-m0)/ m0

其中,m1是给定月份的收入,m0是上个月的收入。因此,从技术上讲,我们需要找到每个月的收入,然后以某种方式将每个月的收入与上一个收入相关联,以便进行上述计算。计算当时如下:

WITHmonthly_revenue as (    SELECT    trunc(add_time,'MM'as month,    sum(amount) as revenue    FROM orders    GROUP BY 1),prev_month_revenue as (    SELECT     month,    revenue,    lag(revenue) over (order by monthas prev_month_revenue -- 上一月收入    FROM monthly_revenue)SELECT   month,  revenue,  prev_month_revenue,  round(100.0*(revenue-prev_month_revenue)/prev_month_revenue,1) as revenue_growthFROM prev_month_revenueORDER BY 1
 

结果输出

monthrevenueprev_month_revenuerevenue_growth
2020-01-01650NULLNULL
2020-02-01125065092.3
2020-03-011500125020

我们还可以按照按城市分组进行统计,查看某个城市某个月份的收入增长情况

WITHmonthly_revenue as (    SELECT     trunc(add_time,'MM'as month,    city,    sum(amount) as revenue    FROM orders    GROUP BY 1,2),prev_month_revenue as (    SELECT     month,    city,    revenue,    lag(revenue) over (partition by city order by monthas prev_month_revenue    FROM monthly_revenue)SELECT month,city,revenue,round(100.0*(revenue-prev_month_revenue)/prev_month_revenue,1as revenue_growthFROM prev_month_revenueORDER BY 2,1
 

结果输出

monthcityrevenuerevenue_growth
2020-01-01上海450NULL
2020-02-01上海950111.1
2020-03-01上海10005.3
2020-01-01北京200NULL
2020-02-01北京30050
2020-03-01北京50066.7
 

需求2:累计求和

累计汇总,即当前元素和所有先前元素的总和,如下面的SQL:

WITHmonthly_revenue as (    SELECT    trunc(add_time,'MM'as month,    sum(amount) as revenue    FROM orders    GROUP BY 1)SELECT month,revenue,sum(revenue) over (order by month rows between unbounded preceding and current rowas running_totalFROM monthly_revenueORDER BY 1
 

结果输出

monthrevenuerunning_total
2020-01-01650650
2020-02-0112501900
2020-03-0115003400

我们还可以使用下面的组合方式进行分析,SQL如下:

SELECT   order_id,   customer_id,   city,   add_time,   amount,   sum(amount) over () as amount_total, -- 所有数据求和   sum(amount) over (order by order_id rows between unbounded preceding and current row) as running_sum, -- 累计求和   sum(amount) over (partition by customer_id order by add_time rows between unbounded    preceding and current row) as running_sum_by_customer,    avg(amount) over (order by add_time rows between 5 preceding and current row) as  trailing_avg -- 滚动求平均FROM ordersORDER BY 1
 

结果输出

order_idcustomer_idcityadd_timeamountamount_totalrunning_sumrunning_sum_by_customertrailing_avg
1A上海2020-01-01 00:00:00.0000002003400200200200
2B上海2020-01-05 00:00:00.0000002503400450250225
3C北京2020-01-12 00:00:00.0000002003400650200216.666667
4A上海2020-02-04 00:00:00.00000040034001050600262.5
5D上海2020-02-05 00:00:00.00000025034001300250260
5D上海2020-02-05 12:00:00.00000030034001600550266.666667
6C北京2020-02-19 00:00:00.00000030034001900500283.333333
7A上海2020-03-01 00:00:00.00000015034002050750266.666667
8E北京2020-03-05 00:00:00.00000050034002550500316.666667
9F上海2020-03-09 00:00:00.00000025034002800250291.666667
10B上海2020-03-21 00:00:00.00000060034003400850
 

需求3:处理重复数据

从上面的数据可以看出,存在两条重复的数据**(5,"D","上海","2020-02-05 00:00:00.000000",250), (5,"D","上海","2020-02-05 12:00:00.000000",300),**显然需要对其进行清洗去重,保留最新的一条数据,SQL如下:

我们先进行分组排名,然后保留最新的那条数据即可:

SELECT *FROM (    SELECT *,    row_number() over (partition by order_id order by add_time descas rank    FROM orders) tWHERE rank=1
 

结果输出

t.order_idt.customer_idt.cityt.add_timet.amountt.rank
1A上海2020-01-01 00:00:00.0000002001
2B上海2020-01-05 00:00:00.0000002501
3C北京2020-01-12 00:00:00.0000002001
4A上海2020-02-04 00:00:00.0000004001
5D上海2020-02-05 12:00:00.0000003001
6C北京2020-02-19 00:00:00.0000003001
7A上海2020-03-01 00:00:00.0000001501
8E北京2020-03-05 00:00:00.0000005001
9F上海2020-03-09 00:00:00.0000002501
10B上海2020-03-21 00:00:00.0000006001

经过上面的清洗过程,对数据进行了去重。重新计算上面的需求1,正确SQL脚本为:

WITHorders_cleaned as (    SELECT *    FROM (        SELECT *,        row_number() over (partition by order_id order by add_time descas rank        FROM orders    )t    WHERE rank=1),monthly_revenue as (    SELECT    trunc(add_time,'MM'as month,    sum(amount) as revenue    FROM orders_cleaned    GROUP BY 1),prev_month_revenue as (    SELECT     month,    revenue,    lag(revenue) over (order by monthas prev_month_revenue    FROM monthly_revenue)SELECT month,revenue,round(100.0*(revenue-prev_month_revenue)/prev_month_revenue,1as revenue_growthFROM prev_month_revenueORDER BY 1
 

结果输出

monthrevenuerevenue_growth
2020-01-01650NULL
2020-02-01100053.8
2020-03-01150050

将清洗后的数据创建成视图,方便以后使用

CREATE VIEW orders_cleaned ASSELECT    order_id,     customer_id,     city,     add_time,     amountFROM (    SELECT *,    row_number() over (partition by order_id order by add_time descas rank    FROM orders)tWHERE rank=1
   

需求4:分组取TopN

分组取topN是最长见的SQL窗口函数使用场景,下面的SQL是计算每个月份的top2订单金额,如下:

WITH orders_ranked as (    SELECT    trunc(add_time,'MM'as month,    *,    row_number() over (partition by trunc(add_time,'MM'order by amount desc, add_time) as rank    FROM orders_cleaned)SELECT     month,    order_id,    customer_id,    city,    add_time,    amountFROM orders_rankedWHERE rank <=2ORDER BY 1
   

需求5:重复购买行为

下面的SQL计算重复购买率:重复购买的人数/总人数*100%以及第一笔订单金额与第二笔订单金额之间的典型差额:avg(第二笔订单金额/第一笔订单金额)

WITH customer_orders as (    SELECT *,    row_number() over (partition by customer_id order by add_time) as customer_order_n,    lag(amount) over (partition by customer_id order by add_time) as prev_order_amount    FROM orders_cleaned)SELECTround(100.0*sum(case when customer_order_n=2 then 1 end)/count(distinct customer_id),1as repeat_purchases,-- 重复购买率avg(case when customer_order_n=2 then 1.0*amount/prev_order_amount endas revenue_expansion -- 重复购买较上次购买差异,第一笔订单金额与第二笔订单金额之间的典型差额FROM customer_orders
 

结果输出

WITH结果输出:

orders_cleaned.order_idorders_cleaned.customer_idorders_cleaned.cityorders_cleaned.add_timeorders_cleaned.amountcustomer_order_nprev_order_amount
1A上海2020-01-01 00:00:00.0000002001NULL
4A上海2020-02-04 00:00:00.0000004002200
7A上海2020-03-01 00:00:00.0000001503400
2B上海2020-01-05 00:00:00.0000002501NULL
10B上海2020-03-21 00:00:00.0000006002250
3C北京2020-01-12 00:00:00.0000002001NULL
6C北京2020-02-19 00:00:00.0000003002200
5D上海2020-02-05 12:00:00.0000003001NULL
8E北京2020-03-05 00:00:00.0000005001NULL
9F上海2020-03-09 00:00:00.000000250

最终结果输出:

repeat_purchasesrevenue_expansion
501.9666666666666668

感谢各位的阅读,以上就是“如何使用SQL窗口函数进行商务数据分析”的内容了,经过本文的学习后,相信大家对如何使用SQL窗口函数进行商务数据分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

sql
AI