0

美好的一天,我正在编写一些代码,其中 -

1) 如果在工作日(周一至周四)东部时区(美国)下午 5:00 之后和工作日东部时区(美国)上午 7:59:59 之前提交请求,则日期将更改为下一个业务一天@ 8:00 AM。

2) 如果请求是在周五下午 5:00 到下周一上午 7:59:59 之前提交的,则时间会按上述方式累计。

3)然后,代码需要检查另一个日期字段以比较“接受”时间(在提交日期或“新”日期的 4 小时内)。

例如:

如果请求 001 是在 2013 年 4 月 17 日凌晨 02:00 提交的,则其新日期将为 2013 年 4 月 17 日上午 8:00。

如果请求 002 是在 04/17/2013 06:45PM 提交的,那么它的新日期将是 04/18/2013 08:00AM。

如果请求 003 是在 04/20/2013 05:45AM(这是星期六)提交的,那么它的新日期将是 04/22/2013 08:00AM。

我一直在将代码拼凑在一起,希望能在最终的代码中将它们整合在一起。


这就是我到目前为止所拥有的(对于日期转换代码)

            ,CASE 
        WHEN to_date(('DATE_REQUESTED'),'DAY',nls_date_language = English) in ('Friday','Saturday'))
        THEN NEXT_DAY(to_date(('DATE_REQUESTED'),'Monday') + 8 / 24)
        ELSE DATE_REQUESTED 
    END as Weekend_Converted

用于检查请求是否在 4 小时内被接受的代码

     SELECT RIT_Request_v.*
     ,CASE 
     WHEN DATE_ACCEPTED IS NULL THEN 'NOT ACKNOWLEDGED'
     WHEN DATE_ACCEPTED > (DATE_REQUESTED + 4 / 24) THEN 'OVER 4 HOURS'
     ELSE 'WITHIN 4 HOURS'
     END AS Acknowledgement

     FROM RIT.RIT_Request_v

     WHERE (("DATE_REQUESTED") BETWEEN trunc(sysdate, 'YYYY') AND trunc(sysdate))

正如我在下面的评论之一中所述,我更新了我的代码,现在出现“无效标识符”错误 -

    SELECT RIT_Request_v.*
    ,CASE WHEN TO_CHAR(DATE_REQUESTED,'D') IN (1,6,7)
          THEN NEXT_DAY(DATE_REQUESTED,'MONDAY')
          ELSE DATE_REQUESTED + 1 END AS Weekend_Converted

    ,CASE WHEN DATE_ACCEPTED IS NULL THEN 'NOT ACKNOWLEDGED'
          WHEN WEEKEND_CONVERTED IS NULL THEN 'NOT ACKNOWLEDGED'
          WHEN DATE_ACCEPTED > (DATE_REQUESTED + 4 / 24) THEN 'OVER 4 HOURS'
          WHEN DATE_ACCEPTED > (Weekend_Converted + 4 / 24) THEN 'OVER 4 HOURS'
          ELSE 'WITHIN 4 HOURS' END AS Acknowledgement

    FROM RIT.RIT_Request_v

    WHERE (("DATE_REQUESTED") BETWEEN trunc(sysdate, 'YYYY') AND trunc(sysdate))

                AND FORM_ID IN         (2011,2014,5007,5036,5039,7007,10000,10001,10005,10007,10011,10024,10025,10029,10032,10033,10034,10035,10036,10037,11011,11013,11999,36001)
4

1 回答 1

0

case生成的weekend_converted唯一似乎是在原始版本中处理周末,并且似乎混淆了周五的任何内容;更新的版本将每个日期都转移到第二天或下周一的同一时间,既丢失了08:00部分,又丢失了在工作日的大部分时间里,您根本不会转移这一天。

您在第二个版本中获得了“无效标识符”,因为您正在定义weekend_converted伪列,然后尝试在同一级别的查询中使用它,这是不允许的。您需要在其中定义一个级别,然后在外部引用它select

这似乎涵盖了您的规则,但我没有用任何额外的日期对其进行测试:

select r.*,
    case
        when to_char(date_requested, 'DY',
                'NLS_DATE_LANGUAGE=English') in ('SAT', 'SUN')
            or (to_char(date_requested, 'DY',
                'NLS_DATE_LANGUAGE=English') = 'FRI'
                and extract(hour from cast(date_requested as timestamp)) >= 17)
        then trunc(next_day(date_requested, 'MON')) + interval '8' hour
        when extract(hour from cast(date_requested as timestamp)) >= 17
        then trunc(date_requested) + interval '1' day + interval '8' hour
        when extract(hour from cast(date_requested as timestamp)) < 8
        then trunc(date_requested) + interval '8' hour
        else date_requested
    end as clock_start
from rit_request_v r;

虽然,NLS_DATE_LANGUAGE如果您不知道它将在哪里运行,虽然强制是一个好主意,但该next_day函数要求 day 参数使用您的本地语言,因此您最好在整个会话中设置它而不是在每个功能的基础。

无论如何,这给出了:

DATE_REQUESTED   DATE_ACCEPTED       FORM_ID CLOCK_START
---------------- ---------------- ---------- ----------------
2013-04-17 02:00 2013-04-17 11:59       5007 2013-04-17 08:00
2013-04-17 18:45 2013-04-18 11:59       5007 2013-04-18 08:00
2013-04-13 05:45                        5007 2013-04-15 08:00

然后,您可以将其用作内联视图或 CTE:

with t as (
select r.*,
    case
        when to_char(date_requested, 'DY',
                'NLS_DATE_LANGUAGE=English') in ('SAT', 'SUN')
            or (to_char(date_requested, 'DY',
                'NLS_DATE_LANGUAGE=English') = 'FRI'
                and extract(hour from cast(date_requested as timestamp)) >= 17)
        then trunc(next_day(date_requested, 'MON')) + interval '8' hour
        when extract(hour from cast(date_requested as timestamp)) >= 17
        then trunc(date_requested) + interval '1' day + interval '8' hour
        when extract(hour from cast(date_requested as timestamp)) < 8
        then trunc(date_requested) + interval '8' hour
        else date_requested
    end as clock_start
from rit_request_v r
where date_requested between trunc(sysdate, 'YYYY') and trunc(sysdate)
and form_id in (2011, 2014, 5007, 5036, 5039, 7007, 10000, 10001, 10005, 10007, 10011, 10024, 10025, 10029, 10032, 10033, 10034, 10035, 10036, 10037, 11011, 11013, 11999, 36001)
)
select t.*,
    case
        when date_accepted is null then 'NOT ACKNOWLEDGED'
        when date_accepted > (clock_start + interval '4' hour)
        then 'OVER 4 HOURS'
        else 'WITHIN 4 HOURS'
    end as acknowledgement
from t;

这使:

DATE_REQUESTED   DATE_ACCEPTED       FORM_ID CLOCK_START      ACKNOWLEDGEMENT
---------------- ---------------- ---------- ---------------- ----------------
2013-04-17 02:00 2013-04-17 11:59       5007 2013-04-17 08:00 WITHIN 4 HOURS
2013-04-17 18:45 2013-04-18 11:59       5007 2013-04-18 08:00 WITHIN 4 HOURS
2013-04-13 05:45                        5007 2013-04-15 08:00 NOT ACKNOWLEDGED

我可以参考,clock_start因为它是在较低级别定义的,在这种情况下是在 CTE 中。

您会注意到我的日期与您的日期格式完全不同。通常我会说您应该将这些字段包装在一个to_char()显示中,但是(a)不清楚这是否会显示在 SQL*Plus 或任何地方,或者会输入其他内容并应保留为日期;如果您确实更改了会话以检查 NLS_DATE_LANGUAGE 那么您可以在那里设置 NLS_DATE_FORMAT 。再次取决于你在哪里运行它。

您可能还会sysdate在错误的级别上进行检查。事实上,它将包括clock_start今天 08:00 的任何时间,因为它正在调整预调整时间。如果将其移到外部,select则可以检查它clock_start是否在该日期范围内。当然,您也可能是故意这样做的。

希望有帮助...

于 2013-04-18T23:52:28.247 回答