将日期范围转换为月份范围,除以金额[不是啥程序]
Posted
技术标签:
【中文标题】将日期范围转换为月份范围,除以金额[不是啥程序]【英文标题】:Convert date range to month range with divided amount [doesn't what procedure]将日期范围转换为月份范围,除以金额[不是什么程序] 【发布时间】:2020-07-30 19:42:45 【问题描述】:表格数据如下,需要转换成输出格式
表格数据
Start_date End_date amount
14apr2020 13may2020 200
15May2020 16June2020 320
输出需求
Start_date End_date amount
14apr2020 30Apr2020 100
1may2020 13may2020 100
15May2020 31May2020 160
1June2020 16June2020 160
【问题讨论】:
mysql 也适用于我,但不适用于程序 @Akina 你真的以这种格式存储日期吗? 不,它只是一个样本。您可以使用任何日期格式给出解决方案 【参考方案1】:Mysql 也适用于我
MySQL 8+ 的解决方案。
查看fiddle - 它详细说明了如何获得所需的结果。
查询本身:
WITH RECURSIVE
-- obtain first day of the least and greatest month/year in a table
cte1 AS ( SELECT LAST_DAY(MIN(Start_date)) + INTERVAL 1 DAY - INTERVAL 1 MONTH firstday,
LAST_DAY(MAX(End_date)) + INTERVAL 1 DAY - INTERVAL 1 MONTH lastday
FROM test ),
-- generate first and last day list for each month/year within the range obtained in cte1
cte2 AS ( SELECT firstday, LAST_DAY(firstday) lastday
FROM cte1
UNION ALL
SELECT firstday + INTERVAL 1 MONTH, LAST_DAY(firstday + INTERVAL 1 MONTH)
FROM cte2
WHERE firstday < ( SELECT lastday
FROM cte1 ) )
-- now obtain desired information
SELECT *,
GREATEST(test.Start_date, cte2.firstday) startday,
LEAST(test.End_date, cte2.lastday) endday,
TIMESTAMPDIFF(MONTH,
LAST_DAY(test.Start_date) + INTERVAL 1 DAY - INTERVAL 1 MONTH,
LAST_DAY(test.End_date) + INTERVAL 1 DAY - INTERVAL 1 MONTH) + 1 months,
test.amount / (TIMESTAMPDIFF(MONTH,
LAST_DAY(test.Start_date) + INTERVAL 1 DAY - INTERVAL 1 MONTH,
LAST_DAY(test.End_date) + INTERVAL 1 DAY - INTERVAL 1 MONTH) + 1) amount_per_month
FROM test
-- joining tables by ranges overlapping
JOIN cte2 ON test.Start_date <= cte2.lastday
AND cte2.firstday <= test.End_date
ORDER BY id, Start_date
出于学习目的,不会删除多余的输出列。调查。
【讨论】:
很好接受,因为它正在工作,但想要没有递归的答案 @AshishMohan 想要没有递归的答案 用静态日期列表生成器(用于 MySQL)替换递归 CTE。或使用 UDTF(用于 HiveQL)。以上是关于将日期范围转换为月份范围,除以金额[不是啥程序]的主要内容,如果未能解决你的问题,请参考以下文章