基于指定日期范围条件添加/复制数据表行生成新数据表的技术需求
搞定按日期范围补全行的需求!
嘿,这个需求我熟——就是要生成一张覆盖指定日期区间的新表,原表里有的日期直接复制对应行,没有的日期就照着原记录的其他字段生成新行对吧?下面分几种常用工具给你具体实现方案,按需pick:
1. Excel用Power Query最省心
Excel的Power Query处理这种数据补全简直是量身定做,步骤超清晰:
- 先把你的原数据表导入Power Query:点「数据」选项卡 → 「自表格/区域」,确认勾选「我的表格有标题」。
- 生成目标日期序列:
- 新建一个空白查询,在公式栏输入:
这里= List.Dates(#date(2018,4,30), 4, #duration(1,0,0,0))#date(2018,4,30)是起始日期,4是日期区间的天数(04/30到05/03刚好4天),#duration(1,0,0,0)表示每天递增一天。 - 把这个日期列表转成表格,列名改成
Due Date。
- 新建一个空白查询,在公式栏输入:
- 合并原表和日期表:
回到原数据的查询页面,点「合并查询」→ 选择刚才新建的日期表,匹配列选Due Date,合并类型选「完全外部」。然后展开合并后的列,保留SiteName、Updater、SomeID这些字段。 - 填充缺失值:
选中SiteName、Updater、SomeID这些列,点「转换」选项卡 → 「填充」→ 「向下填充」(要是你原表每个站点只有一组基础数据,这一步会自动把缺失日期的字段补成和已有行一致的内容)。 - 最后整理下,把结果加载回Excel新工作表就搞定了!
2. 数据库场景用SQL实现
假设你的原表叫site_tasks,目标日期是2018-04-30到2018-05-03,用SQL的话可以这么写(以MySQL为例):
先生成日期序列
WITH date_range AS ( SELECT ADDDATE('2018-04-30', INTERVAL (n-1) DAY) AS due_date FROM ( SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 ) AS numbers )
再左连接原表补全数据
SELECT COALESCE(st.SiteName, (SELECT SiteName FROM site_tasks LIMIT 1)) AS SiteName, dr.due_date AS `Due Date`, COALESCE(st.Updater, (SELECT Updater FROM site_tasks LIMIT 1)) AS Updater, COALESCE(st.SomeID, (SELECT SomeID FROM site_tasks LIMIT 1)) AS SomeID FROM date_range dr LEFT JOIN site_tasks st ON dr.due_date = st.`Due Date`;
小贴士:如果原表有多个不同的
SiteName,得按站点分组生成日期序列,上面的示例是针对单一站点的情况,多站点的话要把站点列表和日期序列做笛卡尔积哦。
3. Python Pandas适合数据分析场景
要是你用Python处理数据,Pandas几行代码就能搞定:
import pandas as pd # 先模拟你的原数据表 df = pd.DataFrame({ 'SiteName': ['Site1', 'Site1'], 'Due Date': ['2018-04-30', '2018-05-01'], 'Updater': ['ABC', '...'], 'SomeID': [11870, ...] }) # 把日期列转成datetime类型,方便后续处理 df['Due Date'] = pd.to_datetime(df['Due Date']) # 定义目标日期范围 date_start = '2018-04-30' date_end = '2018-05-03' target_dates = pd.date_range(start=date_start, end=date_end) # 按站点分组补全日期 final_data = [] for site_name, site_group in df.groupby('SiteName'): # 把分组后的表重新索引到目标日期范围 reindexed_group = site_group.set_index('Due Date').reindex(target_dates) # 填充缺失的字段值(用向前填充,取最近的已有值) reindexed_group['SiteName'] = site_name reindexed_group[['Updater', 'SomeID']] = reindexed_group[['Updater', 'SomeID']].ffill() # 重置索引,把日期列改回原来的名字 final_data.append(reindexed_group.reset_index().rename(columns={'index': 'Due Date'})) # 合并所有站点的结果 final_df = pd.concat(final_data) # 输出看看结果 print(final_df)
这段代码会自动给每个站点补全指定日期范围内的所有日期,缺失日期的字段会沿用该站点最近的已有数据,完美符合你的需求~
内容的提问来源于stack exchange,提问作者NoBullMan
相关产品推荐
相关产品推荐

