如何在 Snowflake 中从 (year, weekOfYear, dayOfWeek) 构建日期?

How to construct date from (year, weekOfYear, dayOfWeek) in Snowflake?

我有一个使用 Snowflake 的情况,我需要从这些部分(年、weekOfYear、dayOfWeek)构造一个日期。即(2022 年第 13 周,周三为 3 周)等于今天的日期 2022-03-30。

虽然这在 Pandas 中是可行的,但 Snowflake 的 day_from_parts() 似乎不支持此功能。是否有其他方法可以根据这 3 条信息构建日期?

对于上下文,我最终试图在我的 dimDate 中为 'weekToDate' 和 'weekToDatePrevYear' 创建标志(上一年比较 实际上不是同一个日期 ,而是周一 - 上一年同一周的今天的星期几)。这些标志还必须考虑跨越两年的周数,以及跨越 53 周的闰年(在这种情况下,它将与上一年的第 52 周进行比较)。我需要构造的日期是前一年的comparisonDate到今天,from parts:

(year(current_date())-1, min(weekOfYear(current_date()), 52), dayOfWeek(current_date()))

提前感谢您的任何建议!

记得设置以下参数以确保, 一年的第一周是包含当年 1 月 1 日的那一周。

ALTER SESSION SET WEEK_OF_YEAR_POLICY = 1;
+----------------------------------+
| status                           |
|----------------------------------|
| Statement executed successfully. |
+----------------------------------+

生成全年日历。 使用来自 @Simeon Pilgrim

select * from
(
 select row_number() over (order by null)-1 as rn
        ,dateadd('day', rn, '2022-01-01'::date) as date_dt,WEEKOFYEAR(dateadd('day', rn, '2022-01-01'::date)
) as woy, DAYOFWEEK(dateadd('day', rn, '2022-01-01'::date)) dow
  from table(generator(rowcount=>365))
 )
 limit 10;
+----+------------+-----+-----+
| RN | DATE_DT    | WOY | DOW |
|----+------------+-----+-----|
|  0 | 2022-01-01 |   1 |   6 |
|  1 | 2022-01-02 |   1 |   0 |
|  2 | 2022-01-03 |   2 |   1 |
|  3 | 2022-01-04 |   2 |   2 |
|  4 | 2022-01-05 |   2 |   3 |
|  5 | 2022-01-06 |   2 |   4 |
|  6 | 2022-01-07 |   2 |   5 |
|  7 | 2022-01-08 |   2 |   6 |
|  8 | 2022-01-09 |   2 |   0 |
|  9 | 2022-01-10 |   3 |   1 |
+----+------------+-----+-----+

根据day-of-week和week-of-year

得到想要的日期
select date_dt from
(
 select row_number() over (order by null)-1 as rn
        ,dateadd('day', rn, '2022-01-01'::date) as date_dt,WEEKOFYEAR(dateadd('day', rn, '2022-01-01'::date)
) as woy, DAYOFWEEK(dateadd('day', rn, '2022-01-01'::date)) dow
  from table(generator(rowcount=>365))
 )
 where woy=13 and dow=4;
+------------+
| DATE_DT    |
|------------|
| 2022-03-24 |
+------------+

有关提取日期部分的详细信息,请参阅 here

@Panjak 我无法让您的代码正常工作...这篇 “根据 day-of-week 和 week-of-year 获取所需的日期”得到了我去年的今天日期。

但是我找到了另一个使用 CTE 的解决方案!这是我对 WTD 和 WTD_PREV_YR 标志的最终看法。注意,它还包含 MTD、MTD_PREV_YR、YTD、YTD_PREV_YR.

create or replace view DIM_DATE as (
    with comparison_date as (
        select
            case
                when weekofyear(current_date()) = 53
                then 52
                else weekofyear(current_date())
            end as comp_week
            , date as comp_date
            from <TABLE>
            where year(comp_date) = year(current_date()) - 1
            and weekofyear(comp_date) = comp_week
            and dayofweek(comp_date) = dayofweek(current_date())
    )
    select distinct
        d.date
        , case
            when weekofyear(date) = weekofyear(current_date())
            and date - current_date() <= 0
            and date - current_date() >= -6
            then 1
            else 0
        end as WTD
        , case
            when weekofyear(date) = weekofyear(c.comp_date)
            and date - c.comp_date <= 0
            and date - c.comp_date >= -6
            then 1
            else 0
        end as WTD_PREV_YR
        , CASE
            WHEN MONTH(DATE) = MONTH(CURRENT_DATE())
            AND DAYOFYEAR(DATE) <= DAYOFYEAR(CURRENT_DATE())
            AND YEAR(DATE) = YEAR(CURRENT_DATE())
            THEN 1
            ELSE 0
        END AS MTD
        , CASE
            WHEN MONTH(DATE) = MONTH(CURRENT_DATE())
            AND DAYOFYEAR(DATE) <= DAYOFYEAR(CURRENT_DATE())
            AND YEAR(DATE) = YEAR(CURRENT_DATE()) - 1
            THEN 1
            ELSE 0
        END AS MTD_PREV_YR
        , CASE
            WHEN DAYOFYEAR(DATE) <= DAYOFYEAR(CURRENT_DATE())
            AND YEAR(DATE) = YEAR(CURRENT_DATE())
            THEN 1
            ELSE 0
        END AS YTD
        , CASE
            WHEN DAYOFYEAR(DATE) <= DAYOFYEAR(CURRENT_DATE())
            AND YEAR(DATE) = YEAR(CURRENT_DATE()) - 1
            THEN 1
            ELSE 0
        END AS YTD_PREV_YR
    from <TABLE> as d
    join comparison_date as c on 1=1
    order by date desc
);