SAP HANA SQL-从星期几开始? WEEK()默认从星期一开始

时间:2020-09-09 20:07:30

标签: sql hana

业务需要从周日开始的一周,但SAP HANA SQL WEEK()从周一开始。如何在星期天开始日历周?我发现一些网页表明存在此问题,例如this one,但没有解决方案。

这里的CALWEEK已经在表中,因此我将重点介绍CALWEEK_DERIVED。 Image shows Calendar week changes on Monday March 9, 2020 instead of Sunday March 8, 2020

3 个答案:

答案 0 :(得分:1)

这里考虑到每年的极端情况的较短变体开始,不需要帮助表:

CREATE OR replace FUNCTION week_sunday(DATE date) RETURNS ret integer AS BEGIN 
    ret = CASE weekday(extract(YEAR FROM date)||'-01-01')
          WHEN 6 THEN
            CASE weekday(date)
            WHEN 6 THEN week(date)
            ELSE week(date)-1
            END
          ELSE
            CASE weekday(date)
            WHEN 6 THEN week(date)+1
            ELSE week(date)
            END
        END;
END;

答案 1 :(得分:0)

以下工作。请注意,派生的周日开始周为 CALWEEK (CALWEEK),并且还会显示其他列以帮助进行验证。

此解决方案要求存在“ _SYS_BI”。“ M_TIME_DIMENSION”,可能必须根据此website底部的注释来生成。

当年份从2017年开始时,我会进行特殊处理-寻找WEEKDAY(TO_DATE(CONCAT(YEAR(date_sap),'-01-01'), 'YYYY-MM-DD')) = 6

我将在下面进行检查:

  • 今年2020
  • 边缘情况1 :年份从星期日开始
  • 边缘案例2 :年份从星期六开始
  • 从1900年-2100年开始的验证SQL

今年2020

-- Current year 2020 started on a Wednesday      
select date_sap, YEAR(date_sap) as year_date_sap, WEEKDAY(date_sap) as weekday_date_sap, WEEK(date_sap) as SAPWEEK,
(CASE     
    -- subtract by 1 when year starts on a Sunday like in 2017
    when WEEKDAY(TO_DATE(CONCAT(YEAR(date_sap),'-01-01'), 'YYYY-MM-DD')) = 6 and
     ((YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap) + 1)) and (WEEKDAY(date_sap) != 6)) THEN CONCAT(YEAR(date_sap), WEEK(date_sap) - 1)
    when WEEKDAY(TO_DATE(CONCAT(YEAR(date_sap),'-01-01'), 'YYYY-MM-DD')) = 6 and
     ((YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap) + 1)) and (WEEKDAY(date_sap) = 6)) THEN CONCAT(YEAR(date_sap), WEEK(date_sap))
    when WEEKDAY(TO_DATE(CONCAT(YEAR(date_sap),'-01-01'), 'YYYY-MM-DD')) = 6 and
     YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap)) THEN CONCAT(YEAR(date_sap), WEEK(ADD_DAYS(date_sap, 1)) - 1)
    when ((YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap) + 1)) and (WEEKDAY(date_sap) != 6)) THEN CONCAT(YEAR(date_sap), WEEK(date_sap))
    when ((YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap) + 1)) and (WEEKDAY(date_sap) = 6)) THEN CONCAT(YEAR(date_sap), WEEK(date_sap) + 1)
    when YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap)) THEN CONCAT(YEAR(date_sap), WEEK(ADD_DAYS(date_sap, 1)))
END) AS CALWEEK
from "_SYS_BI"."M_TIME_DIMENSION" 
-- to eliminate missing values (appears as "?")
where date_sap >= TO_DATE('2019-12-30', 'YYYY-MM-DD') 
      and date_sap <= TO_DATE('2020-01-14', 'YYYY-MM-DD') 
      order by date_sap;   

Shows CALWEEK increments in 2020 on Sunday, January 5th

边缘案例1 :当年份从星期六开始

2011年

-- Same SQL but use:
where date_sap >= TO_DATE('2010-12-20', 'YYYY-MM-DD') 
      and date_sap <= TO_DATE('2011-01-16', 'YYYY-MM-DD') 

Year 2011 - CALWEEK increments on January 1st then Sundays: January 2nd and 9th

边缘情况2 :年份从星期日开始

2017年

-- Same SQL but use:
where date_sap >= TO_DATE('2016-12-20', 'YYYY-MM-DD') 
      and date_sap <= TO_DATE('2017-01-16', 'YYYY-MM-DD') 

Year 2017 - CALWEEK increments on January 1st and the next Sunday: January 8th

1900年至2100年进行的验证SQL

需要具有创建临时表的功能

-- need the ability to create a temporary table
drop table #CALWEEK_TEST;

create local temporary table #CALWEEK_TEST as (
select date_sap, YEAR(date_sap) as year_date_sap, WEEKDAY(date_sap) as weekday_date_sap, WEEK(date_sap) as SAPWEEK,
(CASE     
    -- subtract by 1 when week starts on a Sunday like in 2017
    when WEEKDAY(TO_DATE(CONCAT(YEAR(date_sap),'-01-01'), 'YYYY-MM-DD')) = 6 and
     ((YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap) + 1)) and (WEEKDAY(date_sap) != 6)) THEN CONCAT(YEAR(date_sap), WEEK(date_sap) - 1)
    when WEEKDAY(TO_DATE(CONCAT(YEAR(date_sap),'-01-01'), 'YYYY-MM-DD')) = 6 and
     ((YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap) + 1)) and (WEEKDAY(date_sap) = 6)) THEN CONCAT(YEAR(date_sap), WEEK(date_sap))
    when WEEKDAY(TO_DATE(CONCAT(YEAR(date_sap),'-01-01'), 'YYYY-MM-DD')) = 6 and
     YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap)) THEN CONCAT(YEAR(date_sap), WEEK(ADD_DAYS(date_sap, 1)) - 1)
    when ((YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap) + 1)) and (WEEKDAY(date_sap) != 6)) THEN CONCAT(YEAR(date_sap), WEEK(date_sap))
    when ((YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap) + 1)) and (WEEKDAY(date_sap) = 6)) THEN CONCAT(YEAR(date_sap), WEEK(date_sap) + 1)
    when YEAR(ADD_DAYS(date_sap, 1)) = (YEAR(date_sap)) THEN CONCAT(YEAR(date_sap), WEEK(ADD_DAYS(date_sap, 1)))
END) AS CALWEEK
from "_SYS_BI"."M_TIME_DIMENSION" 
-- to eliminate missing values (appears as "?")
  where date_sap >= TO_DATE('1900-01-01', 'YYYY-MM-DD') 
      and date_sap <= TO_DATE('2100-12-31', 'YYYY-MM-DD') 
      order by date_sap
);   
  

-检查每个CALWEEK的记录数是否始终为1-7 =成功

select distinct count(*) as RECORDS_PER_CALWEEK from #CALWEEK_TEST
group by CALWEEK;

-检查是否有异常的CALWEEK值(期望值1-53)=>成功

select distinct SUBSTRING(CALWEEK, 5) as WEEKONLY from #CALWEEK_TEST
order by WEEKONLY;

答案 2 :(得分:-1)

创建函数:

CREATE OR REPLACE FUNCTION non_iso_week(in_date DATE)
RETURNS week INTEGER LANGUAGE SQLSCRIPT AS BEGIN
  week := CASE EXTRACT(DOW FROM in_date)
            WHEN 0 THEN WEEK(in_date) +1
            ELSE WEEK(in_date)
          END;
END;

然后:

SELECT DISTINCT
  calweek
, non_iso_week(order_date) AS calweek_derived
, order_date
FROM dummy
WHERE order_date >='2020-03-07'
  AND order_date <='2020-03-10'
;
相关问题