2017-04-27 84 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