Правилното използване на IF съществува в SQL

Опитвам се да изпълня следния SQL израз по-долу

    select  FB.FundingSourceID,
          FB.FiscalYearID,
          (FB.FundingBudget-CA.CurrentAmount-DE.CFOApproved) as Amount from    
           (select 
            FundingSourceID, 
            FiscalYearID, 
            SUM(COALESCE(Amount,0)) as FundingBudget 
           from [cap].[FactFundingSourceBudget]
           WHERE IsDeleted = 0
           group by FundingSourceID, FiscalYearID) AS FB

LEFT JOIN (
           select 
            FundingSourceID, 
            FiscalYearID, 
            SUM(COALESCE([Current],0)) as CurrentAmount 
           from [cap].[FactSampledFunding] F
           WHERE F.IsDeleted = 0
           group by  FundingSourceID, FiscalYearID) AS CA on CA.FundingSourceID = FB.FundingSourceID and CA.FiscalYearID = FB.FiscalYearID

LEFT JOIN (
           IF EXISTS (SELECT FundingSourceID, FiscalYearID, SUM(COALESCE(PF.Amount,0))AS CFOApproved FROM [cap].[FactProjectFunding] PF
           INNER JOIN [cap].[DimProject] DP ON DP.ProjectID = PF.ProjectID
           INNER JOIN [dbo].[WFToken] WT ON DP.MemberGUID = WT.EntityGUID
           INNER JOIN [dbo].[WFWorkflowStep] WFT ON WFT.WorkflowStepGUID = WT.WorkflowStepGUID
           WHERE PF.IsDeleted = 0 AND WFT.Name IN ('Cancer Center Review', 'Outpatient Center Review', 'Corporate EVP CFO Review', 'Corporate EVP Review', 'Capital Committee Review')
           GROUP BY  FundingSourceID, FiscalYearID)
           SELECT FundingSourceID, FiscalYearID, SUM(COALESCE(PF.Amount,0))AS CFOApproved FROM [cap].[FactProjectFunding] PF
           INNER JOIN [cap].[DimProject] DP ON DP.ProjectID = PF.ProjectID
           INNER JOIN [dbo].[WFToken] WT ON DP.MemberGUID = WT.EntityGUID
           INNER JOIN [dbo].[WFWorkflowStep] WFT ON WFT.WorkflowStepGUID = WT.WorkflowStepGUID
           WHERE PF.IsDeleted = 0 AND WFT.Name IN ('Cancer Center Review', 'Outpatient Center Review', 'Corporate EVP CFO Review', 'Corporate EVP Review', 'Capital Committee Review')
           GROUP BY  FundingSourceID, FiscalYearID
           ELSE 
           SELECT 0 AS [FundingSourceID], 0 as [FiscalYearID], 0 as [CFOApproved]
           ) AS DE on DE.FundingSourceID = FB.FundingSourceID and DE.FiscalYearID = FB.FiscalYearID
        WHERE
         FB.FundingSourceID != 1

Грешката, която получавам е:

Msg 156, Level 15, State 1, Line 20
Incorrect syntax near the keyword 'IF'.
Msg 102, Level 15, State 1, Line 34
Incorrect syntax near ')'. 

Вероятно се дължи на неправилното използване на израза Exists, може ли някой да ми помогне, моля?


person Emaad Shehzzad    schedule 08.06.2015    source източник


Отговори (1)


Както беше отбелязано, не можете да използвате оператора IF вътре в заявка. Това, което търсите, е начин за обработка на вашите AMOUNT изчисления, когато вашите подзаявки дадат резултат NULL. Следното използва израза ISNULL за справяне с този проблем:

SELECT
  FB.FundingSourceID,
  FB.FiscalYearID,
  ( FB.FundingBudget - ISNULL(CA.CurrentAmount, 0) - ISNULL(DE.CFOApproved, 0) ) AS Amount
FROM
  (
    SELECT
      FundingSourceID,
      FiscalYearID,
      SUM(COALESCE(Amount, 0)) AS FundingBudget
    FROM
      [cap].[FactFundingSourceBudget]
    WHERE
      IsDeleted = 0
    GROUP BY
      FundingSourceID,
      FiscalYearID
  ) AS FB
  LEFT JOIN (
              SELECT
                FundingSourceID,
                FiscalYearID,
                SUM(COALESCE([Current], 0)) AS CurrentAmount
              FROM
                [cap].[FactSampledFunding] F
              WHERE
                F.IsDeleted = 0
              GROUP BY
                FundingSourceID,
                FiscalYearID
            ) AS CA
    ON CA.FundingSourceID = FB.FundingSourceID
       AND CA.FiscalYearID = FB.FiscalYearID
  LEFT JOIN (
              SELECT
                FundingSourceID,
                FiscalYearID,
                SUM(COALESCE(PF.Amount, 0)) AS CFOApproved
              FROM
                [cap].[FactProjectFunding] PF
                INNER JOIN [cap].[DimProject] DP
                  ON DP.ProjectID = PF.ProjectID
                INNER JOIN [dbo].[WFToken] WT
                  ON DP.MemberGUID = WT.EntityGUID
                INNER JOIN [dbo].[WFWorkflowStep] WFT
                  ON WFT.WorkflowStepGUID = WT.WorkflowStepGUID
              WHERE
                PF.IsDeleted = 0
                AND WFT.Name IN ( 'Cancer Center Review',
                                  'Outpatient Center Review',
                                  'Corporate EVP CFO Review',
                                  'Corporate EVP Review',
                                  'Capital Committee Review' )
              GROUP BY
                FundingSourceID,
                FiscalYearID
            ) AS DE
    ON DE.FundingSourceID = FB.FundingSourceID
       AND DE.FiscalYearID = FB.FiscalYearID
WHERE
  FB.FundingSourceID != 1
person JohnS    schedule 08.06.2015
comment
Би било много полезно за вашето отстраняване на грешки и за публикуване на въпроси тук за включен SQL, за да включите номерата на редовете. Той е в SQL Server Management Studio под Инструменти--›Опции--›Текстов редактор и след това отметнете номерата на редовете. - person benjamin moskovits; 09.06.2015
comment
Бен, ще го направя. Благодаря за подкрепата. - person Emaad Shehzzad; 09.06.2015
comment
Вашият SQL е приключенски (много добър), но поддържането на бизнес логиката би било предизвикателство. Направете услуга на себе си и на всички останали в екипа си и незабавно документирайте бизнес логиката на това, което правите. Може да помислите дали SQL се намеси твърде много (знам, че главите на няколко читатели ще изскочат, когато прочетат това) в определен момент, за да съхраните резултатите в променливи на таблица и/или временни таблици и да обедините резултатите. Виждал съм TSQL код да се превръща в reg ex epxressions, които никога не се поддържат, просто се пренаписват всеки път, когато се променят. Очаквам пламъчна война да започне сега. - person benjamin moskovits; 09.06.2015
comment
Главата ми не изскочи, съгласен съм точно с чувството, което @benjaminmoskovits казва. SQL като този е твърде тромав, за да се поддържа с течение на времето. Не съм сигурен за променливите на таблицата, но измислянето как да се раздели това на по-управляем логически поток ще си струва усилието. - person crthompson; 09.06.2015