I'm trying to return NOT NULL and NULL as the result of a CASE statement but I can't find the right way to do it
What I have below is incorrect and underlines the NOT
keyword
SELECT ROW_NUMBER() OVER ( ORDER BY d.cnumber DESC) AS RowNum,
d.cnumber,
d.firstname,
d.lastname,
d.current_email,
d.updated_email,
d.optedin,
d.activated
FROM
Customer d
WHERE (d.optedin =
CASE WHEN @query = 'UNSUBMITTED' OR @query = 'SUBMITTED'
THEN d.optedin
WHEN @query = 'OPTEDIN'
THEN 1
ELSE 0 END) AND
(d.activated =
CASE WHEN @query = 'OPTEDIN' OR @query = 'OPTEDOUT'
THEN d.activated
WHEN @query = 'UNSUBMITTED'
THEN NULL
ELSE NOT NULL END)
activated
is a nullable datetime field. @query
is a varchar parameter
Using a case
in a where
clause is usually an indication you've taken the wrong path. I believe that you'll find you can solve this with more standard logic:
WHERE (@query in ( 'UNSUBMITTED', 'SUBMITTED')
OR (@query = 'OPTEDIN' AND d.optedin = 1)
OR d.optedin = 0)
AND
(@query in ('OPTEDIN', 'OPTEDOUT')
OR (@query = 'UNSUBMITTED' AND d.activated IS NULL)
OR d.activated IS NOT NULL)
I suggest you modify the condition for d.activated to this:
AND (@query = 'UNSUBMITTED' AND d.activated IS NULL OR @query <> 'UNSUBMITTED' AND d.activated IS NOT NULL)
Please note that you do not need to specifically test for this condition:
CASE WHEN @query = 'OPTEDIN' OR @query = 'OPTEDOUT'
THEN d.activated
As it will be covered by OR d.activated IS NOT NULL
in the condition that I have proposed
BTW, for d.optedin you can use the similar:
(@query = 'OPTEDIN' AND d.optedin = 1 OR @query <> 'OPTEDIN' AND d.optedin = 0)
This:
ELSE NOT NULL
is too vague. SQL Server does not know what to return. You have to specify a value that is the same datatype as d.activated.
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.