-- 新增 dws.biz_date() 函数:将 timestamptz 按营业日分割点归属到对应日期 -- 原因:全系统统计时间口径从自然日切换为营业日(默认 08:00 分割), -- 数据库层需要与 Python 侧 business_date() 等价的 SQL 函数, -- 供物化视图和直接查询使用。 -- 影响:物化视图 mv_dws_finance_daily_summary_l1..l4、 -- mv_dws_assistant_daily_detail_l1..l4 的时间过滤条件将依赖此函数 -- 关联需求:Requirements 9.2, 9.4 CREATE OR REPLACE FUNCTION dws.biz_date( ts timestamptz, cutoff_hour int DEFAULT 8 ) RETURNS date LANGUAGE sql IMMUTABLE PARALLEL SAFE AS $$ SELECT (ts - make_interval(hours => cutoff_hour))::date; $$; COMMENT ON FUNCTION dws.biz_date(timestamptz, int) IS '营业日归属函数:将时间戳减去 cutoff_hour 小时后取日期。' '默认 cutoff_hour=8,即 08:00 前的时间戳归属前一天。' '等价于 Python 侧 neozqyy_shared.datetime_utils.business_date()。'; -- 验证 SQL: -- SELECT dws.biz_date('2026-01-15 07:59:59+08'::timestamptz); -- 预期:2026-01-14 -- SELECT dws.biz_date('2026-01-15 08:00:00+08'::timestamptz); -- 预期:2026-01-15 -- SELECT dws.biz_date('2026-01-15 23:59:59+08'::timestamptz); -- 预期:2026-01-15 -- SELECT dws.biz_date('2026-02-01 07:00:00+08'::timestamptz, 8); -- 预期:2026-01-31(月末边界) -- SELECT dws.biz_date(NOW()); -- 预期:当前营业日 -- 回滚: -- DROP FUNCTION IF EXISTS dws.biz_date(timestamptz, int);