Построить дату из частей в SQL Server 2008 - PullRequest
0 голосов
/ 21 февраля 2019

Я использую SQL Server 2008 и пытаюсь сформировать запрос, который будет использовать оператор CASE с вычислением даты, чтобы вернуть одну из двух дат, в зависимости от того, в какой день месяца результаты вычисления.

Цель состоит в том, что если расчет (в запросе ниже) CURRENT_TIMESTAMP + LEAD_TIME приводит к дню между 1-м и 15-м, то назначьте 15-е число этого месяца.В противном случае верните последний день этого месяца.

Например, if CURRENT_TIMESTAMP + LEAD_TIME = 07/12/19, return 07/15/19.If that calculation = 07/16/19, return 07/31/19.

Кажется, что это возможно при использовании DATEFROMPARTS, но я считаю, что поскольку я использую SQL Server 2008, эта функция не определена (это ошибка, которую я возвращаю).Любые идеи по поводу решения?

SQL:

 SELECT I.po_number, 
       I.po_item_number AS 'po_item',
       S.orderentry_date, 
       I.po_req_ship_date, 
       I.ex_factory_date, 
       I.del_indicator,
       H.po_type,
       H.vendor_no,
       CASE WHEN DATEPART(dd,(CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME)) BETWEEN 1 AND 15 
            THEN DATEFROMPARTS(DATEPART(yyyy,(CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME),mm,(CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME),15)
            ELSE DATEFROMPARTS(DATEPART(yyyy,(CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME),mm,(CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME)+1,0))
            END  AS 'LT_CALC',
       H.po_created_by,
       I.comment


FROM   rbk_sap_user..vw_po_header H 
JOIN   rbk_sap_user..vw_po_item I ON H.po_number = I.po_number
JOIN   rbk_sap_user..vw_mm_material MM ON I.material = MM.material
JOIN   (SELECT order_no,
               orderentry_date 
        FROM   asagdwpdx_prod..SimoxOrder1 

        UNION ALL

        SELECT order_no,
               orderentry_date 
        FROM   asagdwpdx_prod..SimoxOrder2 

        UNION ALL 

        SELECT order_no,
               orderentry_date 
        FROM   asagdwpdx_prod..SimoxOrder3
         ) S ON S.order_no = H.ahag_number

WHERE   S.orderentry_date BETWEEN '01/31/2019' AND '02/13/2019'
AND     I.del_indicator <> 'L'
AND     H.po_type NOT IN ('02','06','10','UB')
AND     MM.business_segment_code NOT IN ('420','421','422','424')

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Вы можете преобразовать все части даты в VARCHAR и связать их вместе в формат yyyy-mm-dd, а затем CONVERT в DATETIME.

 SELECT 
 ...
    CASE WHEN DATEPART(dd,(CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME)) BETWEEN 1 AND 15 
            THEN CONVERT(DATETIME, CONVERT(varchar, DATEPART(yyyy,(CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME)))+ '-' + CONVERT(VARCHAR, DATEPART (mm,(CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME)))  + '-' + CONVERT(VARCHAR, 15))
            ELSE DATEADD(DAY, -1, CONVERT(DATETIME, CONVERT(VARCHAR, DATEPART(yyyy,(CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME)))+ '-' + CONVERT(VARCHAR, DATEPART(mm,CURRENT_TIMESTAMP + MM.IAM_MAN_LEAD_TIME)+ 1)  + '-' + CONVERT(VARCHAR, 1)))
            END  AS 'LT_CALC'
...

Обратите внимание, что в операторе ELSE логика для получения последнего дня месяца состоит в том, чтобы перейти к первому дню следующего месяца, а затем использовать функцию DATEADD для вычитания одногодень. Функция SQL Server EOMONTH, представленная в SQL Server 2012, устраняет необходимость в этой логике.

0 голосов
/ 21 февраля 2019

Попробуйте это

SELECT CAST(LEFT(CONVERT(varchar, CURRENT_TIMESTAMP + LEAD_TIME, 103 ),2) as int)

затем

CASE WHEN CAST(LEFT(CONVERT(varchar, CURRENT_TIMESTAMP + LEAD_TIME, 103 ),2) as int) < 15 THEN 
  ....
ELSE
  ....
END
...