2017-04-27 81 views
0

如何根據案例或條件在WHERE CLAUSE內添加條件?SQL根據條件添加到WHERE子句

SELECT C.CallID, A.GroupName,A.Assignee, C.CallStatus, C.RecvdDate, C.Urgency, C.Category, C.CallType, C.KPIreport, C.CallDesc, 
DATEDIFF(DAY, C.RecvdDate,GETDATE()) [DurationInDays], 
CASE 
    WHEN DATEDIFF(DAY, C.RecvdDate,GETDATE()) < 30 
     THEN 'Less than 30' 
    WHEN DATEDIFF(DAY, C.RecvdDate,GETDATE()) >= 30 AND DATEDIFF(DAY, C.RecvdDate,GETDATE()) < 60 
     THEN '30-59' 
    WHEN DATEDIFF(DAY, C.RecvdDate,GETDATE()) >= 60 AND DATEDIFF(DAY, C.RecvdDate,GETDATE()) < 90 
     THEN '60-89' 
    WHEN DATEDIFF(DAY, C.RecvdDate,GETDATE()) >= 90 AND DATEDIFF(DAY, C.RecvdDate,GETDATE()) < 120 
     THEN '90-119' 
    WHEN DATEDIFF(DAY, C.RecvdDate,GETDATE()) >= 120 
     THEN 'Over 120' 
END 

AS 'AgeClassification' 

FROM 
    CallLog C 
    INNER JOIN Asgnmnt A ON C.CallID = A.CallID 
WHERE 
    A.HEATSeq =(SELECT MAX(HEATSeq)FROM Asgnmnt WHERE (CallID = C.CallID)) 
    AND UPPER(A.GroupName) = @GroupName 
    AND LOWER(A.EMail) IN (@Assignee) 
    AND UPPER(C.CallStatus) = @RecordType 

    AND 
    CASE WHEN UPPER(C.CallStatus) = 'CLOSED' THEN 
      C.ClosedDate >= @StartDate AND C.ClosedDate <= @EndDate 
     WHEN UPPER(C.CallStatus) = 'REQUEST TO CLOSE' THEN 
      A.DateResolv >= @StartDate AND A.DateResolv <[email protected] 
    END 




ORDER BY A.GroupName, A.Assignee, C.RecvdDate, C.CallID 

我在這裏的邏輯是,當@RecordType被「封閉」,在WHERE條款必須驗證封閉的日期,如果是@RecordType「中請求關閉」,那麼它必須驗證的解決日期。

我也嘗試使用IF語句來做這件事,但我得到了同樣的錯誤。

+0

column1在=情況下,當條件,那麼重視其他列1端。爲這兩種情況做這件事。 – scsimon

+1

那麼你對這個查詢有什麼問題? –

+0

你能在這裏展示一些樣本數據和期望的輸出嗎? –

回答

2

請嘗試以下...

SELECT C.CallID, 
     A.GroupName, 
     A.Assignee, 
     C.CallStatus, 
     C.RecvdDate, 
     C.Urgency, 
     C.Category, 
     C.CallType, 
     C.KPIreport, 
     C.CallDesc, 
     DATEDIFF(DAY, 
       C.RecvdDate, 
       GETDATE()) AS DurationInDays, 
     CASE 
      WHEN DATEDIFF(DAY, 
          C.RecvdDate, 
          GETDATE()) < 30 THEN 
       'Less than 30' 
      WHEN DATEDIFF(DAY, 
          C.RecvdDate, 
          GETDATE()) BETWEEN 30 AND 59 
       '30-59' 
      WHEN DATEDIFF(DAY, 
          C.RecvdDate, 
          GETDATE()) BETWEEN 60 AND 89 
       '60-89' 
      WHEN DATEDIFF(DAY, 
          C.RecvdDate, 
          GETDATE()) BETWEEN 90 AND 119 
       '90-119' 
      WHEN DATEDIFF(DAY, 
          C.RecvdDate, 
          GETDATE()) >= 120 THEN 
       '120 or over' 
     END AS 'AgeClassification' 
FROM 
    CallLog C 
    INNER JOIN Asgnmnt A ON C.CallID = A.CallID 
WHERE 
    A.HEATSeq =(SELECT MAX(HEATSeq) 
       FROM Asgnmnt 
       WHERE (CallID = C.CallID)) 
    AND UPPER(A.GroupName) = @GroupName 
    AND LOWER(A.EMail) IN (@Assignee) 
    AND UPPER(C.CallStatus) = @RecordType 
    AND ((@RecordType = 'CLOSED' AND 
      C.ClosedDate BETWEEN @StartDate AND @EndDate) OR 
      (@RecordType = 'REQUEST TO CLOSE' AND 
      A.DateResolv BETWEEN @StartDate AND @EndDate) OR 
      (@RecordType <> 'CLOSED' AND 
      @RecordType <> 'REQUEST TO CLOSE') 
     ); 

我已經接受了前四個條件,從你的WHERE條款。對於第五種情況,我沒有使用CASE,而是使用AND,OR和圓括號來選擇等效形式。第一個子條件@RecordType = 'CLOSED' AND C.ClosedDate BETWEEN @StartDate AND @EndDate相當於您的第一個WHEN。第二個子條件@RecordType = 'REQUEST TO CLOSE' AND A.DateResolv BETWEEN @StartDate AND @EndDate)相當於您的第二個WHEN。第三個子條件將允許符合@RecordType既不是CLOSED也不是REQUEST TO CLOSE其他條件的所有記錄。如果您希望在這些情況下返回空集,則應刪除第三個子條件。

從你的第四WHERE條件,其中UPPER(C.CallStatus)等於或者CLOSEDREQUEST TO CLOSE再等會@RecordType。因此,我已在第五種情況下用@RecordType代替UPPER(C.CallStatus)。除了可讀性略高之外,這還消除了語句中的四個函數調用,使其更加高效。

我也從聲明的早期將CASE修改爲使用較少函數調用的等價條件,(可以說)更容易閱讀,並且更清楚地與您的字段別名平行。

如果您有任何問題或意見,請隨時發佈相應評論。

進一步閱讀

"CASE" statement within "WHERE" clause in SQL Server 2008

+0

非常感謝你! – aronccs

+0

不客氣。很高興有幫助。 – toonice

0

你可以嘗試以下

SELECT C.CallID, 
     A.GroupName, 
     A.Assignee, 
     C.CallStatus, 
     C.RecvdDate, 
     C.Urgency, 
     C.Category, 
     C.CallType, 
     C.KPIreport, 
     C.CallDesc, 
     Datediff(DAY, C.RecvdDate, Getdate()) [DurationInDays], 
     CASE 
     WHEN Datediff(DAY, C.RecvdDate, Getdate()) < 30 THEN 'Less than 30' 
     WHEN Datediff(DAY, C.RecvdDate, Getdate()) >= 30 
       AND Datediff(DAY, C.RecvdDate, Getdate()) < 60 THEN '30-59' 
     WHEN Datediff(DAY, C.RecvdDate, Getdate()) >= 60 
       AND Datediff(DAY, C.RecvdDate, Getdate()) < 90 THEN '60-89' 
     WHEN Datediff(DAY, C.RecvdDate, Getdate()) >= 90 
       AND Datediff(DAY, C.RecvdDate, Getdate()) < 120 THEN '90-119' 
     WHEN Datediff(DAY, C.RecvdDate, Getdate()) >= 120 THEN 'Over 120' 
     END         AS 'AgeClassification' 
FROM CallLog C 
     INNER JOIN Asgnmnt A 
       ON C.CallID = A.CallID 
WHERE A.HEATSeq = (SELECT Max(HEATSeq) 
        FROM Asgnmnt 
        WHERE (CallID = C.CallID)) 
     AND Upper(A.GroupName) = @GroupName 
     AND Lower(A.EMail) IN (@Assignee) 
     AND Upper(C.CallStatus) = @RecordType 
     AND C.ClosedDate BETWEEN IIF(Upper(C.CallStatus) = 'CLOSED', @StartDate, C.ClosedDate) 
         AND IIF(Upper(C.CallStatus) = 'CLOSED', @EndDate, C.ClosedDate) 
     AND C.DateResolv BETWEEN IIF(Upper(C.CallStatus) = 'REQUEST TO CLOSE', @StartDate, C.DateResolv) 
         AND IIF(Upper(C.CallStatus) = 'REQUEST TO CLOSE',@EndDate, C.DateResolv) 
ORDER BY A.GroupName, 
      A.Assignee, 
      C.RecvdDate, 
      C.CallID 
1
SELECT C.CallID, A.GroupName,A.Assignee, C.CallStatus, C.RecvdDate, 
     C.Urgency, C.Category, C.CallType, C.KPIreport, C.CallDesc, 
     DATEDIFF(DAY, C.RecvdDate,GETDATE()) [DurationInDays], 
     CASE 
      WHEN (DATEDIFF(DAY, C.RecvdDate,GETDATE()) < 30) THEN 'Less than 30' 
      WHEN (DATEDIFF(DAY, C.RecvdDate,GETDATE()) >= 30 AND DATEDIFF(DAY, C.RecvdDate,GETDATE()) < 60) THEN '30-59' 
      WHEN (DATEDIFF(DAY, C.RecvdDate,GETDATE()) >= 60 AND DATEDIFF(DAY, C.RecvdDate,GETDATE()) < 90) THEN '60-89' 
      WHEN (DATEDIFF(DAY, C.RecvdDate,GETDATE()) >= 90 AND DATEDIFF(DAY, C.RecvdDate,GETDATE()) < 120) THEN '90-119' 
      WHEN (DATEDIFF(DAY, C.RecvdDate,GETDATE()) >= 120) THEN 'Over 120' 
     END AS 'AgeClassification' 
FROM CallLog C 
INNER JOIN Asgnmnt A ON C.CallID = A.CallID 
WHERE A.HEATSeq =(SELECT MAX(HEATSeq)FROM Asgnmnt WHERE (CallID = C.CallID)) 
AND UPPER(A.GroupName) = @GroupName 
AND LOWER(A.EMail) IN (@Assignee) 
AND UPPER(C.CallStatus) = @RecordType 
AND (CASE 
    WHEN UPPER(C.CallStatus) = 'CLOSED' THEN C.ClosedDate 
    WHEN UPPER(C.CallStatus) = 'REQUEST TO CLOSE' THEN A.DateResolv 
END) BETWEEN @StartDate AND @EndDate 
ORDER BY A.GroupName, A.Assignee, C.RecvdDate, C.CallID