简体   繁体   English

从 SQL 中的 iso 周和年获取日期

[英]Get a date from iso week and year in SQL

From iso week and year, I would like to get a date.从iso周和年,我想得到一个日期。 The date should be first day of the week.日期应该是一周的第一天。 First day of the week is Monday.一周的第一天是星期一。 For example iso week 10 and iso year should convert to 2019-03-04.例如,iso 周 10 和 iso 年份应转换为 2019-03-04。 I am using Snowflake我正在使用雪花

Unfortunately, Snowflake doesn't support this functionality natively.不幸的是,Snowflake 本身不支持此功能。

While it's possible to compute manually the date from ISO week and year, it's very complex.虽然可以手动计算 ISO 周和年的日期,但它非常复杂。 So like others suggested, generating a Date Dimension table for this is much easier.因此,就像其他人建议的那样,为此生成日期维度表要容易得多。

Example of a query that can generate it for the lookups (note - this is not a full Date Dimension table - that is typically one row per day, this is one row per week).可以为查找生成它的查询示例(注意 - 这不是完整的日期维度表 - 通常每天一行,这是每周一行)。

create or replace table iso_week_lookup as 
select 
  date_part(yearofweek_iso, d) year_iso, 
  date_part(week_iso, d) week_iso, 
  min(d) first_day 
from (
  select dateadd(day, row_number() over (order by 1) - 1, '2000-01-03'::date) AS d 
  from table(generator(rowCount=>10000))
) 
group by 1, 2 order by 1,2;

select * from iso_week_lookup limit 2;
----------+----------+------------+
 YEAR_ISO | WEEK_ISO | FIRST_DAY  |
----------+----------+------------+
 2000     | 1        | 2000-01-03 |
 2000     | 2        | 2000-01-10 |
----------+----------+------------+

select min(first_day), max(first_day) from iso_week_lookup;
----------------+----------------+
 MIN(FIRST_DAY) | MAX(FIRST_DAY) |
----------------+----------------+
 2000-01-03     | 2027-05-17     |
----------------+----------------+

select * from iso_week_lookup where year_iso = 2019 and week_iso = 10;
----------+----------+------------+
 YEAR_ISO | WEEK_ISO | FIRST_DAY  |
----------+----------+------------+
 2019     | 10       | 2019-03-04 |
----------+----------+------------+

Note, you can play with the constants in create table to create a table of the range you want.请注意,您可以使用create table的常量来创建您想要的范围的表。 Just remember to use Monday as the starting day, otherwise you'll get a wrong value for the first week in the table :)请记住使用星期一作为开始日,否则您将在表中的第一周得到错误的值:)

The date expression to do this is a little complex, but not impossible:执行此操作的日期表达式有点复杂,但并非不可能:

SELECT
    DATEADD( /* Calculate start of ISOWeek as offset from Jan 1st */
      DAY,
      WEEK * 7 - CASE WHEN DAYOFWEEKISO(DATE_FROM_PARTS(YEAR, 1, 1)) < 5 THEN 7 ELSE 0 END
      + 1 - DAYOFWEEKISO(DATE_FROM_PARTS(YEAR, 1, 1)),
      DATE_FROM_PARTS(YEAR, 1, 1)
    )
FROM (VALUES (2000, 1), (2000, 2), (2001, 1), (2002, 1), (2003, 1)) v(YEAR, WEEK);

If you do not have Date Dimension table and/or utilities, as mentioned in the comments, you should parsing it from a textual form.如果您没有日期维度表和/或实用程序,如评论中所述,您应该从文本形式解析它。 But it would be DBMS implementation dependent:但这将取决于 DBMS 实现:

  • In MySQL: STR_TO_DATE(CONCAT(year, ' ', week), '%x %v')在 MySQL 中: STR_TO_DATE(CONCAT(year, ' ', week), '%x %v')
  • In PostgreSQL: TO_DATE(year || ' ' || week, 'IYYY IW')在 PostgreSQL 中: TO_DATE(year || ' ' || week, 'IYYY IW')
    (also Oracle DB would be something similar) (Oracle DB 也是类似的东西)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM