oracle sql pl/sql 如何减去日期/工作周

Posted

技术标签:

【中文标题】oracle sql pl/sql 如何减去日期/工作周【英文标题】:oracle sql pl/sql how to subtract dates/workweeks 【发布时间】:2015-05-22 01:07:37 【问题描述】:

我有如下两列。

我使用 ww1-ww2 计算了差异列。但我在前 2 行没有得到正确的结果。我应该如何修改我的计算?

我尝试了 to_date(ww1)-to_date(ww2) 但没有成功:(

ww1     ww2     difference
201401  201347  54
201401  201346  55
201405  201404  1
201406  201405  1
201408  201405  3
201409  201408  1
201409  201406  3
201409  201407  2
201410  201409  1
201420  201419  1
201425  201424  1
201427  201426  1
201428  201426  2

==================更新1=========

ww1 和 ww2 的日期采用 YYYYWW 格式,其中 YYYY 是年份,WW 是工作周

我的差异列应显示工作周差异。所以考虑到任何一年的 52 周,第 1 行有 6 个。

============update2===================

我看了下面的答案,我觉得这就是我需要的。这就是我在 Excel 中编程的方式,如果有人可以提供 SQL 解决方案,我更愿意。

if(子串(ww1,4)==子串(ww2,4),ww1-ww2,(子串(ww1,4)-子串(ww2,4))*53+子串(ww1,5,6) -substring(ww2,5,6))

其中 substring(ww1,4) 给我 ww1 的前 4 个字符,substring(ww1,5,6) 给我 ww1 的第 5 和第 6 个字符

我需要这样做,因为我每年有 53 周。我将不胜感激上述公式的任何帮助

【问题讨论】:

我不明白。 . . 201347 + 54 = 201401。你的问题没有意义。 201347 不是一个数字,它是 2013 年和第 47 个工作周。我预计这里有 6 个 我认为你需要提取最后两位数,将它们转换为_number,然后减去 @Hawk 你是对的。能回答update2吗? @user2543622 我已经根据您的第二次更新回答了 【参考方案1】:

如果您尝试将这些日期视为 YYYYWW 格式的日期,则需要转换回日期。这样做会很好:

select to_date(ww1, 'YYYYWW') - to_date(ww2, 'YYYYWW')

但是,这是不允许的。所以:

select ( (to_date(substr(ww1, 4) || '-01-01', 'YYYY-MM-DD') + 7 * to_number(substr(ww1, 5, 2)) ) -
         (to_date(substr(ww2, 4) || '-01-01', 'YYYY-MM-DD') + 7 * to_number(substr(ww2, 5, 2))
       ) as DiffInDays

如果您想要以周为单位的差异,则除以 7。

注意:您应该将周存储为一周的开始(或结束)日期。它使此类操作更加更容易。

编辑:

要使此功能跨越多年而无需分数,您需要确保周数从同一日期开始。这是一种方法:

select ( (next_day(to_date(substr(ww1, 4) || '-01-01', 'YYYY-MM-DD'), 'Sun') + 7 * to_number(substr(ww1, 5, 2)) ) -
         (next_day(to_date(substr(ww2, 4) || '-01-01', 'YYYY-MM-DD'), 'Sun') + 7 * to_number(substr(ww2, 5, 2))
       ) as DiffInDays

我确实担心这在几年内可能会出现一次错误。坦率地说,我(或网络上的任何其他人)都知道你对某一年第 n 周的定义。您需要应用您的定义来获得一周的第一天,然后将减法作为天数。

【讨论】:

如果我除以 7,会是余数为 0 的除法吗?我可以得到 5.6 或 6.1 还是总是一个整数? @user2543622 。 . .你知道,在一年之内,它总是一个整数。对于跨越多年的日期,它可能不是整数。解决这个问题有点困难。您可以通过将第一个 to_date() 更改为 next_date(to_date(. . .), XX) 来解决此问题,其中 XX 是基于您对一周的定义。 能否更新您的解决方案?我的一年总是有 53 周 @user2543622 。 . .你的一年怎么总是有 52 周?岁月不是这样建立的;他们有 52 周加 1 天。通常,公司的日历在 7 年中大约有 5 年有 52 周,其余 2 年左右有 53 周。 抱歉,应该是 53 周。这是公司的日历......他们总是有 53 周【参考方案2】:

根据您的第二次更新,我的理解是您正在尝试计算两个日期之间的周差。一种可能的解决方案(每年给出 53 周):

SELECT ( CASE 
           WHEN ( To_number(Substr(ww1, 0, 4)) = To_number(Substr(ww2, 0, 4)) ) 
         THEN 
           To_number(Substr(ww1, -2)) - To_number(Substr(ww2, -2)) 
           WHEN ( To_number(Substr(ww1, 0, 4)) <> To_number(Substr(ww2, 0, 4)) ) 
         THEN ( 
           ( 
         To_number(Substr(ww1, 0, 4) - To_number(Substr(ww2, 0, 4))) * 53 ) + 
           To_number (Substr(ww1, -2)) ) - To_number(Substr(ww2, -2))
         END ) AS diff 
FROM   weeks; 

Fiddle 用于测试

【讨论】:

以上是关于oracle sql pl/sql 如何减去日期/工作周的主要内容,如果未能解决你的问题,请参考以下文章

如何使用间隔 1 分钟在两个日期之间将时间序列数据生成到 Oracle PL/SQL 中的表中?

oracle pl/sql如何定义变量

PL/SQL oracle,使用日期和时间的测试窗口

在 PL/SQL Developer 中运行的日期查询显示时间,但在 Oracle SQL Developer 中不显示

Oracle SQL - 如何在没有 PL/SQL 的情况下检查合同的延续

ORACLE PL/SQL - 使用 SYSDATE 检索特定日期的数据时出现检索问题