简体   繁体   中英

Case Statement(conditional) with CTE

I have a function which i am trying to convert to TVF. But the problem i face is ,the function is multi parter ,with multiple IF conditions.

I was able to convert one condition to TVF and for that i have used CTE.(i received help from this forum earlier). But when i tried to convert the entire function to TVF by including the conditional statements,i am having troubles.

CREATE FUNCTION [dbo].[GetEventDecisionDueDate]
(
       @EventNumber VARCHAR(20),
       @BaseId VARCHAR(25),
          @CheckDate BIT
)

RETURNS DateTime
AS
BEGIN

DECLARE @CurrentStatus VARCHAR(20)
DECLARE @BaseDateTime DateTime
DECLARE @DecisionDueDate DateTime


SELECT @CurrentStatus = (SELECT cis.IncidentStatus
                                 FROM CurrentStatus cis 
                                 INNER JOIN Base r WITH (NOLOCK) ON (cis.BaseId = r.Id)
                                 WHERE (r.EventNumber = @EventNumber) AND r.BaseId = @BaseId)

SELECT @BaseDateTime = (SELECT BaseDateTime FROM Base r 
                          WHERE (r.EventNumber = @EventNumber) AND r.BaseId = @BaseId)

IF @CurrentStatus IN ('0','6') AND @CheckDate = 1
BEGIN

       SET @DecisionDueDate = DATEADD(DAY, 30, @BaseDateTime)

       WHILE @DecisionDueDate < getdate() 
             SET @DecisionDueDate = DATEADD(DAY, 30, @DecisionDueDate)

       DECLARE @FinalJournalDate DateTime

       SELECT @FinalJournalDate = (SELECT TOP 1 ij.Date
                                       FROM EventDetails_Journal ij 
                                       INNER JOIN EventJournal p ON ij.PageId = p.Id 
                                       INNER JOIN Journal f ON p.JournalId = f.Id 
                                       INNER JOIN Base r WITH (NOLOCK) ON (f.BaseId = r.Id)
                                       WHERE (r.EventNumber = @EventNumber AND r.BaseId = @BaseId) AND ij.ReviewType = 'Supervisor Monthly Review' ORDER BY ij.Date DESC)

      IF(DATEADD(DAY, 30, @BaseDateTime) < getdate() AND
           (@FinalJournalDate is null OR DATEADD(DAY, 30, @FinalJournalDate) < getdate()) AND
              DATEADD(DAY, 14, @DecisionDueDate) > DATEADD(DAY, 30, getdate()))
                  SET @DecisionDueDate = DATEADD(DAY, -30, @DecisionDueDate)
         ELSE IF((@FinalJournalDate is not null ) AND (DATEADD(DAY, 30, @FinalJournalDate) >= @DecisionDueDate))
                  SET @DecisionDueDate = DATEADD(DAY, 30, @DecisionDueDate)

END


IF @CurrentStatus IN ('0','6') AND @CheckDate = 0
BEGIN

       SET @DecisionDueDate = DATEADD(DAY, 30, @BaseDateTime)

       WHILE @DecisionDueDate < getdate() 
             SET @DecisionDueDate = DATEADD(DAY, 30, @DecisionDueDate)

       DECLARE @Final30DayDecisonDate DateTime
       DECLARE @Final6MonthDecisonDate DateTime
       DECLARE @Final30DayJournalDate DateTime

       SELECT @Final30DayDecisonDate = (SELECT TOP 1  idps.BaseSupplementDate
                                                FROM EventDetails_Supplements idps 
                                                INNER JOIN EventDetails p ON idps.PageId = p.Id 
                                                INNER JOIN Journal f ON p.JournalId = f.Id 
                                                INNER JOIN Base r WITH (NOLOCK) ON (f.BaseId = r.Id)
                                                WHERE (r.EventNumber = @EventNumber) AND 
                                                             r.BaseId = @BaseId AND idps.IsThirtyDayReview = 1 ORDER BY idps.BaseSupplementDate DESC)

       SELECT @Final6MonthDecisonDate = (SELECT TOP 1  idps.BaseSupplementDate
                                                FROM EventDetails_Supplements idps 
                                                INNER JOIN EventDetails p ON idps.PageId = p.Id 
                                                INNER JOIN Journal f ON p.JournalId = f.Id 
                                                INNER JOIN Base r WITH (NOLOCK) ON (f.BaseId = r.Id)
                                                WHERE (r.EventNumber = @EventNumber) AND 
                                                             r.BaseId = @BaseId AND idps.IsSixMonthReview = 1 ORDER BY idps.BaseSupplementDate DESC)

       SELECT @Final30DayJournalDate = (SELECT TOP 1 ij.Date
                                       FROM EventDetails_Journal ij 
                                       INNER JOIN EventJournal p ON ij.PageId = p.Id 
                                       INNER JOIN Journal f ON p.JournalId = f.Id 
                                       INNER JOIN Base r WITH (NOLOCK) ON (f.BaseId = r.Id)
                                       WHERE (r.EventNumber = @EventNumber AND r.BaseId = @BaseId) AND ij.ReviewType = '30-DAY' ORDER BY ij.Date DESC)

      IF(DATEADD(DAY, 30, @BaseDateTime) < getdate() AND
           (@Final30DayJournalDate is null OR DATEADD(DAY, 30, @Final30DayJournalDate) < getdate()) AND
           (@Final30DayDecisonDate is null OR DATEADD(DAY, 30, @Final30DayDecisonDate) < getdate()) AND
           (@Final6MonthDecisonDate is null OR DATEADD(DAY, 30, @Final6MonthDecisonDate) < getdate()) AND
              DATEADD(DAY, 14, @DecisionDueDate) > DATEADD(DAY, 30, getdate()))
                  SET @DecisionDueDate = DATEADD(DAY, -30, @DecisionDueDate)
      ELSE
         BEGIN
              IF((@Final30DayJournalDate is not null ) AND (DATEADD(DAY, 30, @Final30DayJournalDate) >= @DecisionDueDate))
                  SET @DecisionDueDate = DATEADD(DAY, 30, @DecisionDueDate)

              IF((@Final30DayDecisonDate is not null ) AND (DATEADD(DAY, 30, @Final30DayDecisonDate) >= @DecisionDueDate))
            SET @DecisionDueDate = DATEADD(DAY, 30, @DecisionDueDate)

              IF((@Final6MonthDecisonDate is not null ) AND (DATEADD(DAY, 30, @Final6MonthDecisonDate) >= @DecisionDueDate))
                 SET @DecisionDueDate = DATEADD(MONTH, 6, @DecisionDueDate)
      END          
END
ELSE IF @CurrentStatus = '4' AND @CheckDate = 0
BEGIN

   DECLARE @InactiveBaseSupplementDate DateTime
   DECLARE @LastInactiveBaseSupplementDate DateTime
   DECLARE @LastInactiveJournalDate DateTime

   SELECT @InactiveBaseSupplementDate = (SELECT TOP 1  idps.BaseSupplementDate
                                              FROM EventDetails_Supplements idps 
                                              INNER JOIN EventDetails p ON idps.PageId = p.Id 
                                              INNER JOIN IncidentDetailsPage_Incident idp ON idps.PageId = p.Id 
                                              INNER JOIN Journal f ON p.JournalId = f.Id 
                                              INNER JOIN Base r WITH (NOLOCK) ON (f.BaseId = r.Id)
                                              WHERE (r.EventNumber = @EventNumber) AND 
                                                             r.BaseId = @BaseId AND idp.IncidentStatus = '4' ORDER BY idps.BaseSupplementDate ASC)

        SET @DecisionDueDate = DATEADD(Month, 6, @InactiveBaseSupplementDate)

           WHILE @DecisionDueDate < getdate() 
             SET @DecisionDueDate = DATEADD(Month, 6, @DecisionDueDate)



        SELECT @LastInactiveBaseSupplementDate = (SELECT TOP 1  idps.BaseSupplementDate
                                              FROM EventDetails_Supplements idps 
                                              INNER JOIN EventDetails p ON idps.PageId = p.Id 
                                              INNER JOIN IncidentDetailsPage_Incident idp ON idps.PageId = p.Id 
                                              INNER JOIN Journal f ON p.JournalId = f.Id 
                                              INNER JOIN Base r WITH (NOLOCK) ON (f.BaseId = r.Id)
                                              WHERE (r.EventNumber = @EventNumber) AND 
                                                             r.BaseId = @BaseId AND idp.IncidentStatus = '4' AND idps.IsInactiveReview = 1 ORDER BY idps.BaseSupplementDate DESC)

        SELECT @LastInactiveJournalDate = (SELECT TOP 1 ij.Date
                                              FROM EventDetails_Journal ij 
                                              INNER JOIN EventJournal p ON ij.PageId = p.Id 
                                              INNER JOIN Journal f ON p.JournalId = f.Id
                                              INNER JOIN Base r WITH (NOLOCK) ON (f.BaseId = r.Id)
                                              WHERE (r.EventNumber = @EventNumber) AND 
                                              r.BaseId = @BaseId AND  ij.ReviewType = 'Inactive' ORDER BY ij.Date DESC)

      IF(DATEADD(MONTH, 6, @InactiveBaseSupplementDate) < getdate() AND
           (@LastInactiveJournalDate is null OR DATEADD(MONTH, 6, @LastInactiveBaseSupplementDate) < getdate()) AND
           (@LastInactiveBaseSupplementDate is null OR DATEADD(MONTH, 6, @LastInactiveJournalDate) < getdate()) AND
              DATEADD(DAY, 14, @DecisionDueDate) > DATEADD(MONTH, 6, getdate()))
                  SET @DecisionDueDate = DATEADD(Month, -6, @DecisionDueDate)
      ELSE
         BEGIN
              if((@LastInactiveBaseSupplementDate is not null ) AND (DATEADD(Month, 6, @LastInactiveBaseSupplementDate) >= @DecisionDueDate))
                       SET @DecisionDueDate = DATEADD(Month, 6, @DecisionDueDate)

              if((@LastInactiveJournalDate is not null ) AND (DATEADD(Month, 6, @LastInactiveJournalDate) >= @DecisionDueDate))
                       SET @DecisionDueDate = DATEADD(Month, 6, @DecisionDueDate)          
         END
END

END


GO

As you can see i have multiple if condition and i was able to convert one if condition as shown below. I converted the first part with condition IF @CurrentStatus IN ('0','6') AND @CheckDate = 1

CREATE FUNCTION [dbo].[GetEventDecisionDueDate_test1]
(
       @EventNumber VARCHAR(20),
       @AgencyOri VARCHAR(25),
          @CheckDate BIT
)

RETURNS TABLE 
AS
    RETURN
     WITH X 
          AS (SELECT cis.IncidentStatus AS CurrentIncidentStatus,
                     r.BaseDateTime,
                     FROM CurrentIncidentStatus cis 
                     INNER JOIN Base r WITH (NOLOCK) ON (cis.BaseId = r.Id)
                     WHERE (r.EventNumber = @EventNumber) AND r.AgencyOri = @AgencyOri
                     AND cis.IncidentStatus IN ('0','6')
                     AND @CheckDate = 1)
    SELECT X.CurrentIncidentStatus,
           X.BaseDateTime,
           CA4.DecisionDueDate
    FROM X
    CROSS APPLY (VALUES(DATEADD(DAY, 30, X.BaseDateTime))) CA1(DecisionDueDate)
    CROSS APPLY (VALUES(DATEADD(DAY, 30 * CEILING(( IIF(CAST(GETDATE() AS TIME) > CAST(CA1.DecisionDueDate AS TIME), 1, 0)
                                                    + DATEDIFF(DAY, CA1.DecisionDueDate, GETDATE()) ) / 30.0), CA1.DecisionDueDate))) CA2(DecisionDueDate)
    CROSS APPLY (SELECT TOP 1 ij.Date
                                       FROM EventDetails_Journal ij 
                                       INNER JOIN EventJournal p ON ij.PageId = p.Id 
                                       INNER JOIN Journal f ON p.JournalId = f.Id 
                                       INNER JOIN Base r WITH (NOLOCK) ON (f.BaseId = r.Id)
                                       WHERE (r.EventNumber = @EventNumber AND r.AgencyOri = @AgencyOri) AND 
                                       ij.ReviewType = 'Supervisor Monthly Review' ORDER BY ij.Date DESC) CA3(IncidentJournalDate)
    CROSS APPLY (VALUES ( CASE
                          WHEN ( DATEADD(DAY, 30, X.BaseDateTime) < GETDATE()
                                 AND ( CA3.IncidentJournalDate IS NULL
                                        OR DATEADD(DAY, 30, CA3.IncidentJournalDate) < GETDATE() )
                                 AND DATEADD(DAY, 14, CA2.DecisionDueDate) > DATEADD(DAY, 30, GETDATE()) )
                            THEN DATEADD(DAY, -30, CA2.DecisionDueDate)
                          WHEN( ( CA3.IncidentJournalDate IS NOT NULL )
                                AND ( DATEADD(DAY, 30, CA3.IncidentJournalDate) >= CA2.DecisionDueDate ) )
                            THEN DATEADD(DAY, 30, CA2.DecisionDueDate)
                          ELSE CA2.DecisionDueDate
                        END )) CA4(DecisionDueDate); 
GO

I will try to make it simple. if someone can help me,to include all the conditional logic into one function that would be helpful.

You could perform the same transformation for second part using UNION ALL :

SELECT *
FROM (-- all nested logic here
     )
WHERE @CurrentStatus IN ('0','6') AND @CheckDate = 1
UNION ALL
SELECT *
FROM (-- rest of nested logic here
     )
WHERE @CurrentStatus = '4' AND @CheckDate = 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM