【问题标题】:How to get (year of week number, week number) for a date set如何获取日期集的(周数,周数)
【发布时间】:2020-07-14 11:06:57
【问题描述】:

我想获取一组日期的(周数,周数)连音。

在 Impala SQL 中,有一个函数 weekofyear 给出正确的周数:

select year('2018-12-31'), weekofyear('2018-12-31')

year('2018-12-31')|weekofyear('2018-12-31')|
------------------|------------------------|
              2018|                       1|

但如果想要以字符串格式“yyyyWwk”订购(年、周数)连音,则函数year 不起作用。

有没有一种简洁的方法可以为每个日期获取“yyyyWwk”?上面示例中给出的日期2018-12-31 将产生结果2019W01

这不起作用:

select concat(cast(year(dt) as STRING),'W',lpad(cast(weekofyear(dt) as string),2,"0")) as wk, dt
  from (
select '2018-11-30' as dt 
union 
select '2018-12-31' as dt
union 
select '2019-01-31' as dt
       ) as t
 order by 1, 2;

因为它没有正确排列日期:

wk     |dt        |
-------|----------|
2018W01|2018-12-31|
2018W48|2018-11-30|
2019W05|2019-01-31|

如何获取日期2018-12-31 的“周-年”=2019

【问题讨论】:

  • dayofyear('2018-12-31') 将返回 365,因此您可能可以基于此设计一些逻辑,weekofyear() 为 1,将 year() 结果增加 1。不漂亮但...跨度>
  • @mazaneicha 我也在考虑一些复杂的解决方案。 @gordon-linoff 建议的 date_trunc('week', dt) 方法似乎是最有希望的一个漂亮的解决方案。
  • 这里有个更好的问题:stackoverflow.com/questions/61012874/…
  • 根据 ISO,一年的第一周是该周有 4 天(或更多)天的那一周。如果小于4,则认为是上一年的最后一周。

标签: sql impala week-number


【解决方案1】:

您可以在order by 子句中使用列别名

select year(datecol) as yr, weekofyear(datecol) as wk
  from yourtable
 order by yr, wk

year()weekofyear() 函数都返回 integer 值。

在 GROUP BY、HAVING 和 ORDER BY 子句的顶层允许使用别名,例如GROUP BY 别名来自the documentation

【讨论】:

  • 澄清了问题以解释为什么这不起作用。
【解决方案2】:

如果这只是order by 问题,那么我推测您有某种聚合查询。如果是这样,您可以使用:

order by min(datecol)

这将正确地对整个查询进行排序。

也就是说,如果您想要的信息,那么使用date_trunc() 而不是提取年份和周:

select date_trunc('week', '2018-12-31')

【讨论】:

  • 这个date_trunc 可用于获取同一年一周的所有日期。但weekofyear(date_trunc('week','2018-12-31')) 仍然是 1,year(date_trunc('week','2018-12-31')) 仍然是 2018。
  • @Heikki 。 . .真的。但是您的问题是关于排序数据,而不是关于获得正确的年份。您不需要年份来正确排序数据。
  • 有时很难在一开始就准确地提出问题。实际上可以使用date_trunc 来解决这个问题,因为年份可以从周末开始:year(adddate(date_trunc('week','2018-12-31'),6)) 产生2019
  • @Heikki 。 . .这可能适用于 2018/2019 年,但不适用于第 53 周进入下一年的其他年份。
  • @Heikki 。 . .我想强调一下,这个问题似乎是关于正确排序结果。如果您对年份的准确计算有疑问,请提出问题。
【解决方案3】:

我正试图做与上述类似的事情,但被 2021 年 1 月 1 日落入 2021 年但第 53 周这一事实所吸引!

您(和我)的解决方法是找到该周的星期一(如果我们在星期天,我们向前一天!),然后从中计算星期几和年份。 impala 代码使用 dayofweek 和 days_sub 来到达一周中的星期一(或者如果我们已经在星期一,请坚持下去)。我们做 -2 是因为星期一本身的 dayofweek 是 2。

我最初选择了星期天,但是 impala 中的 weekofyear 在星期一改变,所以星期一更好

with dts as (
    select '2018-11-30' as dt 
    union 
    select '2018-12-31' as dt
    union 
    select '2019-01-01' as dt
    union     
    select '2019-01-31' as dt
    union
    select '2020-12-30' as dt
    union
    select '2020-12-31' as dt
    union
    select '2021-01-01' as dt
    union
    select '2021-01-02' as dt
    union
    select '2021-01-03' as dt
    union
    select '2021-01-04' as dt
    union    
    select '2021-01-09' as dt    
    union
    select '2021-01-10' as dt
    union
    select '2021-01-11' as dt
),
step1 as (
    select
        dt,
        dayofweek(dt) as dayweek,
         dayofweek(dt)-2,
        days_sub(dt, dayofweek(dt)-2) as monOfWeek,
        days_sub(dt, dayofweek(dt)-1) as sunOfWeek
    from dts
)
select 
    dt,
    weekofyear(monOfWeek) as monweeknum,
    year(monofWeek) monyear
from step1 t
order by dt;

导致:

dt monweeknum monyear 2018-11-30 48 2018
2018-12-31 1 2018
2019-01-01 1 2018
2019-01-31 5 2019
2020-12-30 53 2020
2020-12-31 53 2020
2021-01-01 53 2020
2021-01-02 53 2020
2021-01-03 1 2021
2021-01-04 1 2021
2021-01-09 1 2021
2021-01-10 2 2021
2021-01-11 2 2021

关于为什么会发生这种疯狂的更多信息在 https://en.wikipedia.org/wiki/ISO_week_date

还有一个交互式计算器 https://www.timeanddate.com/date/weeknumber.html

【讨论】:

    【解决方案4】:

    问题迟到了,但正在查看问题,通过使用字符串格式,我们可以直接进入 ISO 周 (iw),也可以使用 ISO 年 (iyyy)。

    查询示例:

    select cast(cast('20210124' as date format 'YYYYMMDD') as string format 'iyyyiW')
    

    返回

    202103
    

    【讨论】:

      【解决方案5】:

      选择 to_date(date_sub(to_date(cast('2021-11-23' as timestamp )),(dayofweek(cast('2021-11-23' as timestamp))-2))) week_start_date

      注意:- 一周从星期一开始,然后 - 上面公式中的 2

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-19
        • 2022-06-29
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        • 2014-04-21
        • 1970-01-01
        相关资源
        最近更新 更多