简体   繁体   中英

SQL Server : CASE WHEN in the WHERE Clause with IN

We have a been using some SQL for years now but requirements changed and I am having an issue updating the SQL. We need to use a different IN statement based on the OrderCompletedDate . If before 3/1/19, use on IN statement list and if after, use another. I thought it was a simple CASE WHEN, but not sure now.

Here is the code snippet:

SELECT
    CAST(DATEADD(MONTH, DATEDIFF(MONTH, 0, ER.CreatedDateTime), 0) AS DATE) AS [MonthYear],
    COUNT(ER.RegistrationID) AS TotalCounts
FROM
    EventReg ER
WHERE 
    ER.OptedIn IS NOT NULL
    AND (ER.Phone IS NOT NULL or ER.CellPhone IS NOT NULL)
    AND (ER.BillingZip IN (CASE 
                              WHEN ER.CreatedDateTime >= '3/1/2019 12:00 AM' 
                                 THEN '12345', '45678', '90123'
                           END)
         OR ER.BillingZip NOT IN (CASE 
                                     WHEN ER.CreatedDateTime < '3/1/2019 12:00 AM' 
                                        THEN '07017', '07018',  '07019'
                                  END))
GROUP BY 
    DATEADD(MONTH, DATEDIFF(MONTH, 0, ER.CreatedDateTime), 0)
ORDER BY 
    DATEADD(MONTH, DATEDIFF(MONTH, 0, ER.CreatedDateTime), 0) ASC

This is clearly not correct since you cannot have a list of items in the case/when, as I found out. I wanted to wrap the CASE WHEN on the outside and then do the whole query inside each WHEN, but I just keep getting syntax errors. EX:

AND (
   CASE 
     WHEN ER.CreatedDateTime >= '3/1/2019 12:00 AM' THEN 
       ER.BillingZip IN (
          '12345', '45678', '90123'
       )
     WHEN ER.CreatedDateTime < '3/1/2019 12:00 AM' THEN 
       ER.BillingZip NOT IN (
          '07017', '07018',  '07019'
       )
   END
)

The approach is probably wrong, but I cannot think of a way around it since we need to have the 3/1 break without two different queries altogether, which I am trying to avoid.

Any help would be greatly appreciated!

This should work using an OR

SELECT
   CAST(DATEADD(MONTH, DATEDIFF(MONTH, 0, ER.CreatedDateTime), 0) AS DATE) AS [MonthYear],
   COUNT(ER.RegistrationID) AS TotalCounts
FROM
    EventReg ER
WHERE ER.OptedIn IS NOT NULL
AND (ER.Phone IS NOT NULL or ER.CellPhone IS NOT NULL)


AND (
        (
            ER.CreatedDateTime >= '3/1/2019 12:00 AM' 
            AND ER.BillingZip IN ('12345', '45678', '90123')
        )
        OR -- do OR here to do either one of these
        (
            ER.CreatedDateTime < '3/1/2019 12:00 AM'
            AND ER.BillingZip NOT IN ('07017', '07018',  '07019')
        )
    )


GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, ER.CreatedDateTime), 0)
ORDER BY DATEADD(MONTH, DATEDIFF(MONTH, 0, ER.CreatedDateTime), 0) ASC

Just express this as boolean logic:

AND ( (ER.CreatedDateTime >= '2019-03-01' AND ER.BillingZip IN ('12345', '45678', '90123')) OR
      (ER.CreatedDateTime < '2019-03-01' AND ER.BillingZip NOT IN ('07017', '07018',  '07019'))
    )

Notice that I fixed the date format to be a standard format and the logic so it covers exactly midnight on 2019-03-01.

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