CASE Statement in where clause using equal to and IN - sql

WHERE CONDITION1='ABC'
AND Status =
CASE #Option
WHEN 1 THEN 'True'
WHEN 2 THEN 'False'
WHEN 3 THEN NULL
WHEn 4 THEN **IN ('True', 'False', NULL)**
END
How do I write a query where my first options match directly using = but my last option needs an IN
The above query gives error, but I want something similar to it, which I am not able to find out.

A CASE statement can't return a set of values... but this query should give you the same results:
WHERE CONDITION1='ABC'
AND Status =
CASE
WHEN 1 THEN 'True'
WHEN 2 THEN 'False'
WHEN 3 THEN NULL
WHEN 4 THEN Status
END
Also, note that unless you have ANSI_NULLS OFF, Status will never = NULL... you would need to use IS NULL for this comparison, and you'd need to forgo the CASE statement altogether.

Skip the CASE statement and use OR. And as per ANSI standard don't compare with NULL:
WHERE CONDITION1='ABC'
AND ((#Option = 1 AND Status = 'True') OR
(#Option = 2 AND Status = 'False') OR
(#Option = 3 AND Status IS NULL) OR
(#Option = 4 AND (Status IS NULL OR Status IN ('True', 'False'))))

Related

Update multiple values using IS NULL condition

I just finished migrating an Access database to the SQL Server and I need to fix the Yes/No values to be defaulted to No as their data type conversion is set to bit.
I do this by setting the default value to 0.
However, I want to execute a query to do that as well, but there are multiple bit rows.
I know how to use multiples with the SET command, but how do we use multiple with WHERE? What is the proper way of structuring it?
UPDATE sometable SET
[isConditionOnePassed] = 0
, [isSecondPassed] = 0
, [isThirdPassed] = 0
WHERE [isConditionOnePassed] IS NULL, [isSecondPassed] is NULL, [isThirdPassed] IS NULL
Or is it with an AND? Like boolean logic?
UPDATE sometable SET
[isConditionOnePassed] = 0
, [isSecondPassed] = 0
, [isThirdPassed] = 0
WHERE [isConditionOnePassed] IS NULL and [isSecondPassed] is NULL and [isThirdPassed] IS NULL
Hmmm . . . If you want to set NULL values to another value, you can use COALESCE():
UPDATE sometable
SET isConditionOnePassed = COALESCE(isConditionOnePassed, 0),
isSecondPassed = COALESCE(isSecondPassed, 0),
isThirdPassed = COALESDCE(isThirdPassed, 0)
WHERE isConditionOnePassed IS NULL OR isSecondPassed is NULL OR isThirdPassed IS NULL;
Seems like what you really need is an ISNULL or CASE expression. Here is an example with both:
UPDATE dbo.SomeTable
SET isConditionOnePassed = ISNULL(isConditionOnePassed,0),
isSecondPassed = CASE isSecondPassed WHEN 1 THEN 1 ELSE 0 END;

SELECT WHERE {column} = CASE WHEN {expression} THEN NULL

I have this code which is part of a stored procedure
INSERT INTO #TempTable
/* A few subqueries, about 100 lines */
WHERE (cartera.ClaSucursal = #pIdSucursal OR #pIdSucursal = -1)
AND (cartera.ClaAsesorActual =
CASE
WHEN #pIdAsesor > 0 THEN #pIdAsesor
WHEN #pIdAsesor = 0 THEN NULL
END
OR #pIdAsesor = -1)
/* Rest of my code, about 200 lines */
SELECT * FROM #TempTable
Basically I have a parameter called #pIdAsesor and depending on its value there can be three possible outcomes.
#pIdAsesor = -1 which brings me all entries regardless of the Id value
#pIdAsesor = sumId which brings me all entries with given Id
#pIdAsesor = 0 which brings me all entries with NULL as the Id
Outcomes 1 and 2 work flawlessly, but scenario 3 doesn't bring back results.
null isn't a value - it's the lack thereof. null is never equal to anything (not even another null), but you can check for it explicitly with the is operator.
You could ditch the case expression and construct this logic with a series of ors:
AND ((#pIdAsesor = -1) OR
(#PIdAsesor = 0 AND cartera.ClaAsesorActual IS NULL) OR
(#pIdAsesor = cartera.ClaAsesorActual))
You can't use = for null in case when result comes null but = null doesn't work. You have to use is null.

SQL CASE query condition

I have the following condition in my stored procedure:
[DMO].[DriverModelName] =
CASE WHEN ISNULL(#driverModelName,'NotSet') = 'NotSet' THEN
[DMO].[DriverModelName]
ELSE
#driverModelName
END
This implies that when I pass 'NotSet' to varchar parameter #driverModelName, it should return all the rows but for some reason it's returning only those rows which has a value in column DriverModelName & omitting the null value rows.
Am I doing anything wrong here?
This is because NULL == NULL = FALSE, for the purpose of the WHERE clause, unless you set ANSI_NULLS to OFF. Example:
SET ANSI_NULLS OFF
IF NULL = NULL
PRINT 'TRUE'
ELSE
PRINT 'FALSE'
SET ANSI_NULLS ON
IF NULL = NULL
PRINT 'TRUE'
ELSE
PRINT 'FALSE'
The result is:
TRUE
FALSE
In order to get all rows, including the NULL values, you should use
(#driverModelName IS NULL OR [DMO].[DriverModelName] = #driverModelName)
For references:
http://www.sqlservercentral.com/blogs/steve_jones/2010/10/13/common-sql-server-mistakes-1320-equals-null/
SQL is null and = null
Why does NULL = NULL evaluate to false in SQL server
Additional Reading on Catch-All queries:
Catch-all Queries by Gail Shaw
The Curse and Blessings of Dynamic SQL by Erland Sommarskog
Well if [DMO].[DriverModelName] is ever NULL what are you expecting the result of this CASE be? Isn't this missing a ISNULL() around that column too?
ISNULL([DMO].[DriverModelName], 'NotSet') =
CASE WHEN ISNULL(#driverModelName,'NotSet') = 'NotSet' THEN
[DMO].[DriverModelName]
ELSE
#driverModelName
END
You cant say NULL = #someValue, it must be IS NULL or handle both sides with ISNULL()

Select Logic in Query. Is this possible in Oracle?

Im trying to implement some sort of logic on the select statement of the query. I want it so that if no attribute is given, or if the inAttribute is 'NONE'; it will return the date and ALL of the values (compprice, compspread,price,spread,run).
If a value was given to in attribute then i want it to return the value it requested for (Refer to the case statement i tried to do).
Below is my attempt at it, and it is just not working. Any help please?
SELECT
mi.date,
IF inAttribute = '' THEN
mi.compprice,
mi.compspread,
mi.price,
mi.spread,
mi.run
ELSE
CASE inAttribute
WHEN 'CP' THEN mi.compprice,
WHEN 'CS THEN mi.compspread,
WHEN 'MP' THEN mi.price,
WHEN 'MS' THEN mi.spread,
WHEN 'R' THEN mi.run
END
END IF
FROM userValueTable mi
WHERE mi.index_family = inIdxFamily
AND mi.index_id = inIdxId
AND mi.date_>= inStartDate
AND mi.date_<= inEndDate
ORDER by mi.date_ ASC;
Few remarks You can't have variable column list from one line to another. '' is equal to NULL, comparing NULL with equality ( = ) is always false. you can have some fixed number of columns and set value of any column using CASE clause.
Oracle doesn't have an IF for SQL. Use CASE instead - it can act like a C/C#/Java/etc switch - case as you have it in your query, and it can also act like an if.
Also, as mentioned above:
You're stuck with returning a constant number of columns unless you use dynamic SQL
In Oracle, '' is treated as NULL so instead of = '' use IS NULL.
If you don't want to go to Dynamic SQL, you could add a "type" column to your select list and then null out any inapplicable values. Your downstream logic could pick the values to use (or ignore) based on the type. Here's an example:
SELECT
mi.date,
CASE
WHEN inAttribute IS NULL THEN 'inAttrNull'
ELSE 'inAttrNotNull'
END AS RecordType,
CASE WHEN inAttribute IS NULL THEN mi.compprice END AS compprice,
CASE WHEN inAttribute IS NULL THEN mi.compspread END AS compspread,
CASE WHEN inAttribute IS NULL THEN mi.price END AS price,
CASE WHEN inAttribute IS NULL THEN mi.spread END AS spread,
CASE WHEN inAttribute IS NULL THEN mi.run END AS run,
CASE inAttribute
WHEN 'CP' THEN mi.compprice
WHEN 'CS' THEN mi.compspread
WHEN 'MP' THEN mi.price
WHEN 'MS' THEN mi.spread
WHEN 'R' THEN mi.run
END AS SpecialValue
FROM userValueTable mi
... and your WHERE and ORDER BY clauses
You'll get a result set something like this:
RecordType compprice compspread price spread run specialvalue
------------- ---------- ---------- ---------- ---------- ---------- ------------
inAttrNotNull (null) (null) (null) (null) (null) 1234.56
inAttrNull 111.11 222.22 333.33 444.44 555.55 (null)
I know this isn't what you wanted, but it may be something you can work with as an alternative.
There is no IF in Oracle SQL, only in PL/SQL. You have to rewrite it to CASE. The same as you did in your query in ELSE part (you missed a single closing quote after 'CS' THEN...).
SELECT ...
(CASE WHEN inAttribute IS NULL THEN mi.compprice
WHEN .... THEN...
WHEN .... THEN...
...
ELSE ...
END) AS some_column_alias
FROM ...

CASE expression syntax error SQL

I have researched everywhere but still can't seem to fix a simple error:
Running Microsoft SQL server:
UPDATE copyprogmaster
SET active =
CASE
WHEN active = 1 THEN active = 0
WHEN active = 0 THEN active = 1
ELSE active
END
WHERE source = 'Mass_Mail'
my error is :
Line 4: Incorrect syntax near '='.
Remove the = after the THEN, so:
UPDATE copyprogmaster
SET active =
CASE
WHEN active = 1 THEN 0
WHEN active = 0 THEN 1
ELSE active
END
WHERE source = 'Mass_Mail'
You already have active = after the SET on the second line.
You do not need to repeat "active =" after THEN
UPDATE copyprogmaster
SET active =
CASE
WHEN active = 1 THEN 0
WHEN active = 0 THEN 1
ELSE active
END
WHERE source = 'Mass_Mail'
Here's an example from the documentation at http://msdn.microsoft.com/en-us/library/ms181765.aspx
USE AdventureWorks2008R2;
GO
SELECT ProductNumber, Category =
CASE ProductLine
WHEN 'R' THEN 'Road'
WHEN 'M' THEN 'Mountain'
WHEN 'T' THEN 'Touring'
WHEN 'S' THEN 'Other sale items'
ELSE 'Not for sale'
END,
Name
FROM Production.Product
ORDER BY ProductNumber;
GO
Based on your query, I assume the active field is bit or int (assuming that int field has only values 0, 1, or NULL). In that case, I believe that you can write the query as following:
UPDATE dbo.copyprogmaster
SET active = active ^ 1
WHERE source = 'Mass_Mail'
Notice that the query can handle NULL values and also the rows #1, #4 and #6 in the screenshot are unchanged. Screenshot #1 shows table structure and screenshot #2 displays sample execution of the above query.
Hope that helps.
Screenshot #1:
Screenshot #2: