如何动态将当前年与上一年数据分别存储至两张不同表?
按动态年份分表存储数据的实现方案
一、先修正年份筛选逻辑(区分两种时间范围)
你当前的WHERE条件是基于滚动365天的时间窗口,和自然年份(1月1日至12月31日)的范围不一致。以下是两种需求对应的动态筛选逻辑:
1. 按自然年份划分(推荐,符合常规业务统计习惯)
- 当前自然年数据:
TEST_DATE >= DATE_TRUNC('year', CURRENT_DATE) AND TEST_DATE < DATE_TRUNC('year', CURRENT_DATE) + INTERVAL '1 year' - 上一自然年数据:
TEST_DATE >= DATE_TRUNC('year', CURRENT_DATE) - INTERVAL '1 year' AND TEST_DATE < DATE_TRUNC('year', CURRENT_DATE)
这种写法会自动根据当前日期计算对应自然年区间,比如2024年运行时,当前年范围是2024-01-01至2025-01-01(不含),上一年是2023-01-01至2024-01-01(不含),完全支持年份动态切换,无需硬编码年份。
2. 按滚动365天窗口划分(若业务需求如此)
简化你当前的条件,避免重复计算:
- 近365天数据:
TEST_DATE >= CURRENT_DATE - INTERVAL '365 days' - 上一个滚动年数据(再往前365天):
TEST_DATE >= CURRENT_DATE - INTERVAL '730 days' AND TEST_DATE < CURRENT_DATE - INTERVAL '365 days'
二、动态分表存储的实现方法
要将对应年份数据写入不同表(比如data_2024、data_2023)且支持年份动态切换,核心是动态生成目标表名,以下是两种常用场景的实现方式:
1. 纯SQL脚本实现(以PostgreSQL为例)
通过变量+动态SQL自动生成表名并写入数据:
DO $$ DECLARE current_year INT := EXTRACT(YEAR FROM CURRENT_DATE)::INT; last_year INT := current_year - 1; BEGIN -- 创建并写入当前年数据到对应表 EXECUTE format(' CREATE TABLE IF NOT EXISTS data_%s AS SELECT * FROM your_source_table WHERE TEST_DATE >= DATE_TRUNC(''year'', CURRENT_DATE) AND TEST_DATE < DATE_TRUNC(''year'', CURRENT_DATE) + INTERVAL ''1 year'' ', current_year); -- 创建并写入上一年数据到对应表 EXECUTE format(' CREATE TABLE IF NOT EXISTS data_%s AS SELECT * FROM your_source_table WHERE TEST_DATE >= DATE_TRUNC(''year'', CURRENT_DATE) - INTERVAL ''1 year'' AND TEST_DATE < DATE_TRUNC(''year'', CURRENT_DATE) ', last_year); END $$;
脚本会自动根据当前年份创建(若不存在)并写入对应表,次年运行时会自动切换到2025和2024的表。
2. ETL工具实现(如Airflow、DataX)
将年份作为参数传入任务,适合定期调度场景:
- 通过工具内置函数获取当前年份(比如Airflow的
{{ execution_date.year }}) - 配置两个同步任务:
- 任务1:源表筛选当前年数据,写入目标表
data_{{ execution_date.year }} - 任务2:源表筛选上一年数据,写入目标表
data_{{ execution_date.year - 1 }}
全程无需硬编码年份,调度任务会自动适配当前时间。
- 任务1:源表筛选当前年数据,写入目标表
三、注意事项
- 确保目标表结构与源表一致,或在创建表时指定正确的字段和数据类型
- 若为增量同步,需添加
TEST_DATE的增量条件,避免重复写入数据 - 不同数据库的日期函数语法有差异,比如MySQL用
DATE_FORMAT替代DATE_TRUNC,SQL Server用DATEADD+DATEDIFF组合,需根据你的数据库调整函数写法
内容的提问来源于stack exchange,提问作者npool
相关产品推荐
相关产品推荐

