如何基于每月最后周五的变量实现表的条件截断或删除?
实现基于全量刷新标记的表数据清理逻辑
问题背景
你已定义标记每月最后一个周五的变量:
SET is_full_refresh = ( CASE WHEN DAY(LAST_DAY(current_date)) - DAY(current_date) < 7 AND DAYOFWEEK(current_date) = 5 THEN TRUE ELSE FALSE END );
同时有一段按日期条件删除数据的脚本:
SET sales_date = ( SELECT MIN(max_date) AS date FROM ( SELECT date_type, MAX(date) AS max_date FROM sales_table GROUP BY date_type )a ); SET process_from_date = (SELECT COALESCE(DATEADD('MONTH', -3, DATE_TRUNC('MONTH', $sales_date))::DATE, '2019-01-01'::DATE)); DELETE FROM sales_table WHERE date >= $process_from_date;
希望实现:当is_full_refresh为TRUE时截断sales_table,否则执行上述条件删除操作,询问是否只需补充SELECT语句即可实现。
解决方案
- 不能仅靠补充SELECT语句实现,因为
CASE是返回值的表达式,无法用来控制执行不同的DDL/DML语句(TRUNCATE和DELETE是两种独立操作,无法通过CASE分支触发)。 - 需要借助SQL环境支持的流程控制语句实现分支逻辑,以下以Snowflake为例(你的语法风格匹配Snowflake):
-- 1. 定义全量刷新标记 SET is_full_refresh = ( CASE WHEN DAY(LAST_DAY(current_date)) - DAY(current_date) < 7 AND DAYOFWEEK(current_date) = 5 THEN TRUE ELSE FALSE END ); -- 2. 定义日期变量(全量刷新时不会用到,但提前定义不影响) SET sales_date = ( SELECT MIN(max_date) AS date FROM ( SELECT date_type, MAX(date) AS max_date FROM sales_table GROUP BY date_type )a ); SET process_from_date = (SELECT COALESCE(DATEADD('MONTH', -3, DATE_TRUNC('MONTH', $sales_date))::DATE, '2019-01-01'::DATE)); -- 3. 条件分支执行对应操作 IF ($is_full_refresh) THEN TRUNCATE TABLE sales_table; ELSE DELETE FROM sales_table WHERE date >= $process_from_date; END IF;
- 其他环境适配提示:
- PostgreSQL需用PL/pgSQL编写存储过程或匿名块,通过
IF...THEN...ELSE实现逻辑; - 若在dbt、Airflow等ETL工具中,可直接使用工具自带的条件判断语法,根据
is_full_refresh的值选择执行对应SQL块。
- PostgreSQL需用PL/pgSQL编写存储过程或匿名块,通过
内容的提问来源于stack exchange,提问作者Nader Esmael
相关产品推荐
相关产品推荐

