如何检查具有多个条件的SQL CASE?

时间:2017-11-14 23:02:08

标签: sql sql-server case

我有两张桌子。账户ACC和FinancialTrans FT

FinancialTrans表如下:

AcctID  TransTypeCode   DateOfTrans
123     TOLL            2016-06-06 00:00:00.000
123     TOLL            2016-06-02 00:00:00.000
123     TOLL            2016-04-28 00:00:00.000
123     PYMT            2016-03-11 00:00:00.000
123     TOLL            2015-12-22 00:00:00.000
123     TOLL            2015-12-22 00:00:00.000

要求是:
如果任何账户在过去两年内没有'TOLL'或'PYMT',则打印'Flag'

SELECT ACC.Field1
      ,ACC.Field2
      ,ACC.Field3
      ,ACC.Field4
      ,CASE WHEN  
        (SELECT Max(DateOfTrans) FROM FinanceTrans FT
         WHERE ACC.AccountID = FT.AcctID
               AND (TransTypeCode = 'TOLL' AND DateOfTrans >= DATEADD(year, -2, GETDATE()))
               AND (TransTypeCode = 'PYMT' AND DateOfTrans >= DATEADD(year, -2, GETDATE()))
             GROUP BY AcctID, TransTypeCode) IS NULL
        THEN 'Flag'
        ELSE ''
       AND AS NoNo_Flag

FROM Accounts ACC

WHERE Condition 1, Condition 2...

4 个答案:

答案 0 :(得分:2)

试试这个:

SELECT
    acc.*,
    CASE WHEN f.acctid IS NULL THEN 'flag' ELSE '' END AS flag_noTollOrPmt
FROM
    accounts acc LEFT OUTER JOIN
    (SELECT 
        AcctID, 
        MAX(DateOfTrans) AS max_dateOfTrans_TollOrPmt
    FROM 
        FinanceTrans 
    WHERE 
        DateOfTrans >= DATEADD(YEAR, -2, GETDATE()) AND
        TransTypeCode IN( 'TOLL' , 'PYMT') 
    GROUP BY 
        AcctID) f ON
    acc.acctid = f.acctid

答案 1 :(得分:1)

您应该使用窗口功能。逻辑是查看两种事务类型的最大日期。然后该标志取决于与当前日期的关系。

select a.*,
       (case when max(case when transtype in ('TOLL', 'PYMT') then DateOfTrans end) over
                       (partition by acctid) >= dateadd(year, -2, getdate())
             then 0 else 1
        end) as flag
from accounts;

答案 2 :(得分:1)

我可能误解了这个问题,在这种情况下我可以改进我的答案。您似乎只需要检查子查询中是否存在记录。那么到那个程度你真的需要做一个聚合吗?并且,尝试使用EXISTS:

SELECT ACC.Field1, ACC.Field2, ACC.Field3, ACC.Field4, 
       CASE WHEN NOT EXISTS
           (SELECT DateOfTrans 
            FROM FinanceTrans FT
            WHERE ACC.AccountID = FT.AcctID
                  AND (TransTypeCode = 'TOLL' AND DateOfTrans >= DATEADD(year, -2, GETDATE()))
                  AND (TransTypeCode = 'PYMT' AND DateOfTrans >= DATEADD(year, -2, GETDATE())))
       THEN 'Flag'
       ELSE ''
       END AS NoNo_Flag
FROM Accounts ACC
WHERE [*condition*]

答案 3 :(得分:0)

所以这就是我解决这个问题的方法:

我为每个创建了一个单独的列,然后将这些详细信息存储在临时表中 然后我使用条件从临时表中提取数据来创建标志。

我的代码如下:

SELECT ACC.Field1
      ,ACC.Field2
      ,ACC.Field3
      ,ACC.Field4
      ,(SELECT Max(DateOfTrans) FROM FinanceTrans FT
        WHERE ACC.AccountID = FT.AcctID
          AND TransTypeCode = 'TOLL'
        GROUP BY AcctID, TransTypeCode) LastTollDate
      ,(SELECT Max(DateOfTrans) FROM FinanceTrans FT
        WHERE ACC.AccountID = FT.AcctID
          AND TransTypeCode = 'PYMT'
        GROUP BY AcctID, TransTypeCode) LastPymtDate

INTO #Temp_Data

FROM Accounts ACC

WHERE Condition 1, Condition 2...



SELECT ACC.Field1
      ,ACC.Field2
      ,ACC.Field3
      ,ACC.Field4
      ,CASE WHEN LastTollDate >= DATEADD(year, -2, GETDATE())
        AND LastPymtDate >= DATEADD(year, -2, GETDATE())
        THEN 'Flag'
        ELSE ''
       END AS Flag

FROM #Temp_Data