我有一个用于时间表的水晶报告日期范围。(我继承的东西)我正在寻求有关如何将其更改为 Oracle 的 sql 查询的一部分以获取 SSRS 报告的帮助
Today - Round((((Today - Date (1998,11,23 ))/14) - Truncate((Today - Date (1998,11,23 ))/14)) * 14,0)
提前谢谢史蒂文(他对 sql 和 ssrs 报告还是很陌生)
我有一个用于时间表的水晶报告日期范围。(我继承的东西)我正在寻求有关如何将其更改为 Oracle 的 sql 查询的一部分以获取 SSRS 报告的帮助
Today - Round((((Today - Date (1998,11,23 ))/14) - Truncate((Today - Date (1998,11,23 ))/14)) * 14,0)
提前谢谢史蒂文(他对 sql 和 ssrs 报告还是很陌生)
您所拥有的内容的直接翻译似乎是:
trunc(sysdate) - round((((trunc(sysdate) - date '1998-11-23')/14) - trunc((trunc(sysdate) - date '1998-11-23')/14)) * 14,0)
但是您可以将其简化为:
trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14)
这两个trunc(sysdate)
调用给出了当前日期,时间截断为午夜,因此当前为 2016-02-12。如果你减去你的固定开始日期(大概是你系统中的第一个时期?)你会得到一个数字,来自 Oracle 如何进行日期时间算术:
select trunc(sysdate) - date '1998-11-23' from dual;
TRUNC(SYSDATE)-DATE'1998-11-23'
---------------------------------------
6290
因为两个日期都在午夜,所以这是一个整数 - 今天和固定日期之间的整数天数。如果将其除以 14,则得到 449.285,即 449 个整个两周周期,以及当前周期的 0.285。您的原始计算采用该值并删除了截断的版本 449 以仅留下 0.285,然后将其乘以 14 以将剩余部分作为整数返回,即 4。
但这正是函数给你的mod()
——“n2 的余数除以 n1”。换句话说,mod(6290, 14)
是 6290 除以 14 的余数,这也是 4。它从一个表达式而不是两个表达式得到相同的结果。
因此,您只需从当天减去计算出的 4 值,今天您将回到 2016 年 2 月 8 日。
查看选择的生成日期如何变化:
with t (dt) as (
select trunc(sysdate) - level from dual connect by level < 21
)
select dt,
dt - round((((dt - date '1998-11-23')/14) - trunc((dt - date '1998-11-23')/14)) * 14) long_version,
dt - mod(dt - date '1998-11-23', 14) period_start,
dt - mod(dt - date '1998-11-23', 14) + 14 period_end
from t
order by dt;
DT LONG_VERSION PERIOD_START PERIOD_END
---------- ------------ ------------ ----------
2016-01-23 2016-01-11 2016-01-11 2016-01-25
2016-01-24 2016-01-11 2016-01-11 2016-01-25
2016-01-25 2016-01-25 2016-01-25 2016-02-08
2016-01-26 2016-01-25 2016-01-25 2016-02-08
...
2016-02-06 2016-01-25 2016-01-25 2016-02-08
2016-02-07 2016-01-25 2016-01-25 2016-02-08
2016-02-08 2016-02-08 2016-02-08 2016-02-22
2016-02-09 2016-02-08 2016-02-08 2016-02-22
2016-02-10 2016-02-08 2016-02-08 2016-02-22
2016-02-11 2016-02-08 2016-02-08 2016-02-22
您可以通过在结果中添加天数来获得期末,或者使用 14 天后的开始日期单独计算它。如果您正在查找某个范围内的记录,则可以执行以下操作:
where some_date >= trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14)
and some_date < trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14) + 14
如果没有一个日期在午夜之后有时间(时间表可能就是这种情况),您可以使用between
并在 13 天后结束该期间,正如您在评论中建议的那样:
where some_date between trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14)
and trunc(sysdate) - mod(trunc(sysdate) - date '1998-11-23', 14) + 13
不过,我更喜欢 >= 和 < 方法,因为当您对时间也很重要的数据执行某些操作时,它不会让您失望。