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 中的表中?
在 PL/SQL Developer 中运行的日期查询显示时间,但在 Oracle SQL Developer 中不显示