您的位置:首页 > 娱乐 > 八卦 > 重庆企业_企业自助建站软件_网络推广违法吗_如何快速推广自己的产品

重庆企业_企业自助建站软件_网络推广违法吗_如何快速推广自己的产品

2025/4/29 12:22:10 来源:https://blog.csdn.net/weixin_48935611/article/details/146964689  浏览:    关键词:重庆企业_企业自助建站软件_网络推广违法吗_如何快速推广自己的产品
重庆企业_企业自助建站软件_网络推广违法吗_如何快速推广自己的产品

横扫SQL面试

📌日期交叉问题

在这里插入图片描述


“如何统计品牌优惠活动的总天数、统计每月有效的订阅用户数(Netflix 会员),避免重复计算重叠日期?”
“怎样快速合并时间区间,精准计算有效天数?”


🍬🍬1.品牌优惠天数统计

现有各品牌优惠周期表(promotion_info)如下,其记录了每个品牌的每个优惠活动的周期,其中同一品牌的不同优惠活动的周期可能会有交叉。

promotion_idbrandstart_dateend_date
1oppo2021-06-052021-06-09
2oppo2021-06-112021-06-21
3vivo2021-06-052021-06-15
4vivo2021-06-102021-06-22
5redmi2021-06-012021-06-10
6redmi2021-06-152021-06-22
7huawei2021-06-032021-06-13
8huawei2021-06-182021-06-27

现要求统计每个品牌的优惠总天数,若某个品牌在同一天有多个优惠活动,则只按一天计算。期望结果如下:

brandpromotion_day_count
vivo18
oppo16
redmi18
huawei21

其实跟会话划分问题很像~


1:获取上一个活动的结束日期 ✅✅✅

在这里插入图片描述

brandstart_dateend_dateprev_end
oppo2021-06-052021-06-09null
oppo2021-06-112021-06-212021-06-09
vivo2021-06-052021-06-15null
vivo2021-06-102021-06-222021-06-15
redmi2021-06-012021-06-10null
redmi2021-06-152021-06-222021-06-10
huawei2021-06-032021-06-13null
huawei2021-06-182021-06-272021-06-13

2:判断是否开启新组 ✅✅✅

在这里插入图片描述

brandstart_dateend_dateis_new_group判断逻辑说明
oppo2021-06-052021-06-090前驱为 null,默认不新开组
oppo2021-06-112021-06-2112021-06-11 > 2021-06-09+1 → 新组
vivo2021-06-052021-06-150前驱为 null
vivo2021-06-102021-06-2202021-06-10 ≤ 2021-06-15+1 → 不新开组
redmi2021-06-012021-06-100前驱为 null
redmi2021-06-152021-06-2212021-06-15 > 2021-06-10+1 → 新组
huawei2021-06-032021-06-130前驱为 null
huawei2021-06-182021-06-2712021-06-18 > 2021-06-13+1 → 新组

3:分配组 ID ✅✅✅

在这里插入图片描述

brandstart_dateend_dategroup_id计算逻辑说明
oppo2021-06-052021-06-090初始组,is_new_group=0 → group_id=0
oppo2021-06-112021-06-211is_new_group=1 → group_id=0+1=1
vivo2021-06-052021-06-150初始组
vivo2021-06-102021-06-220is_new_group=0 → group_id 保持 0
redmi2021-06-012021-06-100初始组
redmi2021-06-152021-06-221is_new_group=1 → group_id=0+1=1
huawei2021-06-032021-06-130初始组
huawei2021-06-182021-06-271is_new_group=1 → group_id=0+1=1

4:合并区间并计算天数 ✅✅✅

在这里插入图片描述

brandmerged_startmerged_end合并逻辑说明
oppo2021-06-052021-06-09组 0 的合并区间
oppo2021-06-112021-06-21组 1 的合并区间
vivo2021-06-052021-06-22组 0 的合并区间(两个活动重叠)
redmi2021-06-012021-06-10组 0 的合并区间
redmi2021-06-152021-06-22组 1 的合并区间
huawei2021-06-032021-06-13组 0 的合并区间
huawei2021-06-182021-06-27组 1 的合并区间

最终结果:统计总天数 ✅✅✅

select brand,sum(datediff(merged_end, merged_start) + 1) as promotion_day_count
from t4
group by brand;

在这里插入图片描述

输出结果

brandpromotion_day_count天数计算逻辑
oppo(2021-06-09 - 2021-06-05) +1 = 5
+ (2021-06-21 - 2021-06-11) +1 = 11
16
5 + 11 = 16
vivo(2021-06-22 - 2021-06-05) +1 = 18单组合并
redmi(2021-06-10 - 2021-06-01) +1 = 10
+ (2021-06-22 - 2021-06-15) +1 = 8
18
10 + 8 = 18
huawei(2021-06-13 - 2021-06-03) +1 = 11
+ (2021-06-27 - 2021-06-18) +1 = 10
21
11 + 10 = 21

🍬🍬2.员工项目参与天数统计

某公司记录了员工参与不同项目的时间段,一个员工可能同时参与多个项目,不同项目的时间段可能存在重叠。现在需要计算每个员工实际参与项目的总天数(重叠日期不重复计算)。

员工项目参与表(employee_projects)结构如下:

emp_idemp_nameproject_idproject_namestart_dateend_date
1001张三P001电商系统2023-03-012023-03-10
1001张三P002支付系统2023-03-052023-03-15
1001张三P003数据分析2023-03-202023-03-25
1002李四P004移动端开发2023-03-012023-03-08
1002李四P005后台优化2023-03-102023-03-18
1003王五P006测试平台2023-03-012023-03-20
1003王五P007自动化部署2023-03-152023-03-25
1003王五P008安全审计2023-03-222023-03-30

统计每个员工实际参与项目的总天数(重叠日期不重复计算):

emp_idemp_nametotal_days
1001张三21
1002李四17
1003王五30

套路一样滴:

1.获取前一个项目的结束日期✅✅✅

在这里插入图片描述

emp_idemp_namestart_dateend_dateprev_end
1001张三2023-03-012023-03-10NULL
1001张三2023-03-052023-03-152023-03-10
1001张三2023-03-202023-03-252023-03-15
1002李四2023-03-012023-03-08NULL
1002李四2023-03-102023-03-182023-03-08
1003王五2023-03-012023-03-20NULL
1003王五2023-03-152023-03-252023-03-20
1003王五2023-03-222023-03-302023-03-25

2.第二步:判断是否新区间 (t2)✅✅✅

在这里插入图片描述

emp_idemp_namestart_dateend_dateis_new_group
1001张三2023-03-012023-03-100
1001张三2023-03-052023-03-150
1001张三2023-03-202023-03-251
1002李四2023-03-012023-03-080
1002李四2023-03-102023-03-181
1003王五2023-03-012023-03-200
1003王五2023-03-152023-03-250
1003王五2023-03-222023-03-300

3.第三步:分配组ID (t3)✅✅✅

在这里插入图片描述

emp_idemp_namestart_dateend_dategroup_id
1001张三2023-03-012023-03-100
1001张三2023-03-052023-03-150
1001张三2023-03-202023-03-251
1002李四2023-03-012023-03-080
1002李四2023-03-102023-03-181
1003王五2023-03-012023-03-200
1003王五2023-03-152023-03-250
1003王五2023-03-222023-03-300

4.第四步:合并区间 (t4)✅✅✅

在这里插入图片描述

emp_idemp_namegroup_idmerged_startmerged_end
1001张三02023-03-012023-03-15
1001张三12023-03-202023-03-25
1002李四02023-03-012023-03-08
1002李四12023-03-102023-03-18
1003王五02023-03-012023-03-30

5.第五步:最终结果✅✅✅

在这里插入图片描述

emp_idemp_nametotal_days计算说明
1001张三15(3/15-3/1=14)+1=15
+ (3/25-3/20=5)+1=6 → 21
1002李四15(3/8-3/1=7)+1=8
+ (3/18-3/10=8)+1=9 → 17
1003王五30(3/30-3/1=29)+1=30
with 
-- 第一步:获取每个员工前一个项目的结束日期
t1 as (selectemp_id,emp_name,start_date,end_date,-- 使用lag窗口函数获取同一个员工前一个项目的结束日期lag(end_date) over(partition by emp_id order by start_date) as prev_endfrom employee_projects
),-- 第二步:判断是否开始新的日期区间(不与前一个区间重叠)
t2 as (selectemp_id,emp_name,start_date,end_date,-- 判断逻辑:如果当前开始日期 > 前一个结束日期+1天,则是新区间casewhen start_date > coalesce(prev_end + interval 1 day, '1900-01-01') then 1else 0end as is_new_groupfrom t1
),-- 第三步:为每个连续的日期区间分配组ID
t3 as (selectemp_id,emp_name,start_date,end_date,-- 使用累加和的方式为连续的日期区间分配相同的组IDsum(is_new_group) over(partition by emp_id order by start_date) as group_idfrom t2
),-- 第四步:合并每个组内的日期区间(取最早开始日期和最晚结束日期)
t4 as (selectemp_id,emp_name,group_id,-- 合并后的开始日期(组内最早的开始日期)min(start_date) as merged_start,-- 合并后的结束日期(组内最晚的结束日期)max(end_date) as merged_endfrom t3group by emp_id, emp_name, group_id
)-- 最终结果:计算每个员工不重叠的项目参与总天数
selectemp_id,emp_name,-- 计算每个合并区间的天数并求和(datediff+1包含首尾两天)sum(datediff(merged_end, merged_start) + 1) as total_days
from t4
group by emp_id, emp_name
order by emp_id;

日期交叉 与 会话划分问题类似 大家可以看看

在这里插入图片描述