我有一个要求,我必须在 Snowflake 中重建 SAP HANA 视图。该视图使用 SAP HANA 中的
workdays_between()
函数,该函数用于根据工厂日历查找两个日期之间的工作日,它使用 TFACS
表来计算工作日。在 Snowflake 中我们没有 workdays_between()
功能所以请告诉我我们如何在 Snowflake 中使用这个功能来计算工作日。
我试图在 Snowflake 中创建一个 UDF,但在 Snowflake 中重新创建
workdays_between()
的逻辑非常困难,因为它根据国家代码(TFACS
)、年份(IDENT
)和月列。所以请帮助在 Snowflake 中创建逻辑。SAP 中的 TFACS 表:
SAP 中的 TFACS 表有各种列,如 IDENT(国家代码)、JAHR(年)、MON01 ....MON12 每个月的工作日详细信息。
国家代码 TFACS 表数据:IN 年份:2023 这里 1 表示工作日,0 表示假期,包括周六和周日。
我必须在 Snowflake 中构建类似的东西。但是在 Snowflake workdays_between() 函数中不可用,如果有人有任何解决方案,请告诉我。
JAHR
例如:
create or replace function workdays_between(
date1 date, date2 date, country_region string
)
returns number
language python
runtime_version = '3.8'
packages = ('holidays')
handler='x'
as
$$
from datetime import date, timedelta
import holidays
def x(start_date, end_date, country_region):
days = (end_date - start_date).days + 1
if days <= 0:
return 0
parsed_country_region = country_region.split('-')
country = parsed_country_region[0]
region = (
parsed_country_region[1]
if len(parsed_country_region) > 1
else None
)
range_years = range(start_date.year, end_date.year+1)
holidays_dict = holidays.country_holidays(
country
, subdiv=region
, years=range_years
)
weekdays = [0, 1, 2, 3, 4]
working_days = [day for day in range(days) if (start_date + timedelta(day)).weekday() in weekdays and
(start_date + timedelta(day)) not in holidays_dict]
return len(working_days)
$$
;
相关:
select workdays_between('2022-01-01', '2022-10-10', 'US-CA');
-- 192
功能。
完整的文章可以在这里找到,但是解决方案代码是这样的:
workdays_between
现在我可以简单地跑了
create view SF_SAP_FACTORY_CALENDAR as (
with tfacs_pivot as (
select IDENT, JAHR, MON01 as DAY_FLAGS, '01' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON02 as DAY_FLAGS, '02' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON03 as DAY_FLAGS, '03' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON04 as DAY_FLAGS, '04' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON05 as DAY_FLAGS, '05' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON06 as DAY_FLAGS, '06' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON07 as DAY_FLAGS, '07' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON08 as DAY_FLAGS, '08' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON09 as DAY_FLAGS, '09' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON10 as DAY_FLAGS, '10' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON11 as DAY_FLAGS, '11' as "MONTH" from TFACS UNION ALL
select IDENT, JAHR, MON12 as DAY_FLAGS, '12' as "MONTH" from TFACS),
day_point as (
select tfp.*
, length(DAY_FLAGS) AS NUM_FLAGGED_DAYS
, ROW_NUMBER() OVER (PARTITION BY "JAHR", "MONTH" ORDER BY "JAHR", "MONTH" ) as FLAG_POINTER
from tfacs_pivot tfp
cross join table ( generator (rowcount =>32)) d
)
select dp.*
, date_from_parts (JAHR, "MONTH", FLAG_POINTER) as FACTORY_DATE
, substr(dp.DAY_FLAGS, FLAG_POINTER , 1) as day_marker
, to_boolean (DAY_MARKER) as IS_WORKING_DAY
from day_point dp
where FLAG_POINTER <= NUM_FLAGGED_DAYS);
获取我想要的信息:
select FACTORY_DATE, IS_WORKING_DAY from SF_SAP_FACTORY_CALENDAR;
设置此视图并可能在生产环境中具体化后,创建模仿 SAP HANA 等价物的
FACTORY_DATE IS_WORKING_DAY
2018-01-01 FALSE
2018-01-02 TRUE
2018-01-03 TRUE
2018-01-04 TRUE
2018-01-05 TRUE
2018-01-06 FALSE
2018-01-07 FALSE
2018-01-08 TRUE
... ...
功能只是一个小的附加步骤:
WORKDAYS_BETWEEN