SQL日期的传递表日期

时间:2019-05-25 14:13:37

标签: db2

想知道如何将RECEIVEDDATETIME传递给以下语句。我的SQL语句中缺少什么?

由于Mark Ba​​rinstein,我向CALENDAR表和TESTDATA表添加了内部联接,以将T.RECEIVEDDATETIME作为原始示例的日期传递。

此语句从我的tblCalendar获取C.WORKDATE,但是我需要传递T.RECEIVEDDATETIME来获取所需的“ DUEDATE”。

我创建了一个“ tblCalendar”,因为我读到它可以更轻松地引用真实工作日的日历...以排除周末和节假日并解释leap年。不确定这是否是最佳实践,但似乎很直接地不为异常编写代码。因此,我创建了tblCalendar,其中包含从2017年到2050年及节假日的所有日期。下面的数据仅代表了2019年1月的部分数据,因为我还没有找到在此处附加表格的方法:

tblCalendar (partial)
DATE        NUMDAYOFWK       DAYOFWK      HOLIDAY
01/01/2019    3              Tuesday      YES
01/02/2019    4              Wednesday  
01/03/2019    5              Thursday   
01/04/2019    6              Friday 
01/05/2019    7              Saturday   
01/06/2019    1              Sunday 
01/07/2019    2              Monday 
01/08/2019    3              Tuesday    
01/09/2019    4              Wednesday  
01/10/2019    5              Thursday   
01/11/2019    6              Friday 
01/12/2019    7              Saturday   
01/13/2019    1              Sunday 
01/14/2019    2              Monday 
01/15/2019    3              Tuesday    
01/16/2019    4              Wednesday  
01/17/2019    5              Thursday   
01/18/2019    6                  Friday 
01/19/2019    7              Saturday   
01/20/2019    1              Sunday 
01/21/2019    2              Monday       YES

tblTestData表包含核心数据,我在其中引用了报告所需的所有字段。

tblTestData Columns (partial) - DeliveryDays would reference the 2nd parameter BusDayAdd that was noted in the previous SQL.

ID                  RECEIVEDDATE       DeliveryDays     Address
T-20190116-255      01/16/2019          2             1234 Address
T-20190117-255      01/17/2019          2             3657 Address
T-20190118-222      01/18/2019          2             9999 Address
T-20190119-255      01/19/2019          2
T-20190120-255      01/20/2019
T-20190121-255      01/21/2019
T-20190303-1        03/03/2019

考虑到我的tblTestData中的RECEIVEDDATETIME并参考tblCalendar表以排除周末和节假日以给出正确的到期日,所需的最终结果如下所示。

ID              RECEIVEDDATE            DeliveryDays    DueDate    Address
T-20190116-255  1/16/2019                2             1/18/2019     1234 Address
T-20190117-255  1/17/2019   2   1/22/2019   3657 Address
T-20190118-222  1/18/2019   2   1/23/2019   9999 Address
T-20190119-255  1/19/2019   2   1/23/2019   10000 Address
T-20190120-255  1/20/2019   2   1/23/2019   10001 Address
T-20190121-255  1/21/2019   2   1/23/2019   10002 Address
T-20190121-256  1/22/2019   2   1/24/2019   10003 Address
T-20190303-1    3/3/2019    3   3/6/2019    10004 Address
T-20190121-257  3/15/2019   7   3/26/2019   10005 Address

我通过重写代码以包装SQL字符串以传递表“ RECEIVEDDATETIME”来尝试各种语句,但是每次“ DUEDATE”返回{NULL}时。

SELECT T.ID, VARCHAR_format(T.RECEIVEDDATETIME, 'MM/DD/YYYY') RECDATE, 

(select VARCHAR_FORMAT(WORKDATE,'MM/DD/YYYY') DUEDATE 

from 

(Select
WORKDATE, T.RECEIVEDDATETIME,
sum(case when C.HOLIDAY='YES' or C.NUMDAYOFWK in (7,1) then 0 else 1 end) over  (order by C.WORKDATE) BUSDAYADD

from tblCALENDAR C

--ADDED INNER JOIN TO GET T.RECEIVEDDATETIME TO FEED AUTOMATICALLY FROM TESTDATA TABLE

INNER JOIN TESTDATA T
      ON 
VARCHAR_FORMAT(C.WORKDATE, 'MM/DD/YYYY') = VARCHAR_FORMAT(T.RECEIVEDDATETIME,'MM/DD/YYYY')

where C.WORKDATE > VARCHAR_FORMAT(T.RECEIVEDDATETIME,'MM/DD/YYYY')) -- 1-st PARAMETER TO CAPTURE RECEIVEDDATETIME 

WHERE BUSDAYADD = ? -- 2-nd parameter to add the number of days needed to be added to RECEIVEDDATETIME 

order by WORKDATE --3rd Parameter
fetch first 1 row only) 

FROM TESTDATA T
WHERE ID = 'T-20190303-1'

运行SQL时,DUEDATE的结果为{NULL}:

ID              RECDATE     DUEDATE
T-20190303-1    03/03/2019  {NULL}

结果应为:

 ID             RECDATE     DUEDATE
 T-20190303-1   03/03/2019  03/05/2019

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

DUEDATE的SELECT是

INNER JOIN TESTDATA T
   ON VARCHAR_FORMAT(C.WORKDATE, 'MM/DD/YYYY') = VARCHAR_FORMAT(T.RECEIVEDDATETIME,'MM/DD/YYYY')
where C.WORKDATE > VARCHAR_FORMAT(T.RECEIVEDDATETIME,'MM/DD/YYYY'))

这意味着您加入平等,然后限制为工作日期> Receiveddatetime 可能是问题所在...

答案 1 :(得分:0)

您在两个表中提供的数据不一致:tblTestData表中除第一个记录外的所有记录的日历都为时过早。
让我提供绝对相同的查询,我之前已经将其发送给您另一个问题。

with tblCalendar (DATE, HOLIDAY) as (values
  (date(to_date('01/16/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/17/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/18/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/19/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/20/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/21/2019', 'MM/DD/YYYY')), 'YES')

, (date(to_date('01/22/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/23/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/24/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/25/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/26/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/27/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/28/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/29/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/30/2019', 'MM/DD/YYYY')), '')
, (date(to_date('01/31/2019', 'MM/DD/YYYY')), '')
, (date(to_date('02/01/2019', 'MM/DD/YYYY')), '')
, (date(to_date('02/02/2019', 'MM/DD/YYYY')), '')
, (date(to_date('02/03/2019', 'MM/DD/YYYY')), '')
, (date(to_date('02/04/2019', 'MM/DD/YYYY')), '')
, (date(to_date('02/05/2019', 'MM/DD/YYYY')), '')

)
, tblTestData (ID, RECEIVEDDATE, DeliveryDays) as (values
  ('T-20190116-255', date(to_date('01/16/2019', 'MM/DD/YYYY')), 2)
, ('T-20190117-255', date(to_date('01/17/2019', 'MM/DD/YYYY')), 2)
, ('T-20190118-222', date(to_date('01/18/2019', 'MM/DD/YYYY')), 2)
, ('T-20190119-255', date(to_date('01/19/2019', 'MM/DD/YYYY')), 2)
, ('T-20190120-255', date(to_date('01/20/2019', 'MM/DD/YYYY')), 2)
, ('T-20190121-255', date(to_date('01/21/2019', 'MM/DD/YYYY')), 2)
, ('T-20190121-256', date(to_date('01/22/2019', 'MM/DD/YYYY')), 2)
, ('T-20190303-1'  , date(to_date('01/23/2019', 'MM/DD/YYYY')), 3)
, ('T-20190121-257', date(to_date('01/24/2019', 'MM/DD/YYYY')), 7)
)
select m.*, t.date as DUEDATE
--, dayofweek(date) as DAYOFWK, dayname(date) as DAY
from tblTestData m
, table
(
  select date
  from table 
  (
    select 
      date
    , sum(case when HOLIDAY='YES' or dayofweek(date) in (7,1) then 0 else 1 end) over (order by date) as dn_
    from tblCalendar t
    where t.date > m.RECEIVEDDATE
  )
  where dn_ = m.DeliveryDays
  fetch first 1 row only
) t;

结果是:

ID              RECEIVEDDATE DAYS   DUEDATE
--------------  ------------ ----   ----------
T-20190116-255    2019-01-16    2   2019-01-18
T-20190117-255    2019-01-17    2   2019-01-22
T-20190118-222    2019-01-18    2   2019-01-23
T-20190119-255    2019-01-19    2   2019-01-23
T-20190120-255    2019-01-20    2   2019-01-23
T-20190121-255    2019-01-21    2   2019-01-23
T-20190121-256    2019-01-22    2   2019-01-24
T-20190303-1      2019-01-23    3   2019-01-28
T-20190121-257    2019-01-24    7   2019-02-04