I want to apply different where condition in SQL based on value of other column something like below.
Sorry, I am updating my que with more specific requirement
SELECT * FROM TABLEDetails
WHERE CASE WHEN
ConfigValue = 'FALSE' THEN
(ConfigAmount != 0 OR ConfigVolume != 0)
WHEN ConfigValue = 'TRUE' THEN
(ConfigAmount != 0 OR ConfigVolume <Here, it should allow Zero too with other values>
END
Simply use ANDs and ORs:
SELECT * FROM TABLEDetails
WHERE (ConfigValue = 'FALSE' AND ConfigVolume != 0)
OR (ConfigValue = 'TRUE' AND ConfigVolume = 0)
CASE WHEN returns results expressions, and no comparisons like in your query.
As stated by #Pred, a WHERE clause must contain comparisons.
See MSDN.
After your edit (which completely changed the requirement BTW), I guess something like this could work, but the question is quite unclear now:
SELECT * FROM TABLEDetails
WHERE (ConfigValue = 'FALSE' AND (ConfigAmount != 0 OR ConfigVolume != 0))
OR (ConfigValue = 'TRUE' AND (ConfigAmount != 0 OR ConfigVolume IN (0, 1, 2, ... /* add as many values you need*/)))
#X.L.Ant wrote a correct and excellent answer, but to complete the list of the possible solutions. Here is one with the CASE..WHEN clause:
SELECT
*
FROM
TABLEDetails
WHERE
ConfigValue = CASE
WHEN ConfigVolume != 0 THEN 'FALSE'
WHEN ConfigVolume = 0 THEN 'TRUE'
END
Please note, that the CASE..WHEN clause returns NULL if there is no ELSE condition and none of the WHEN conditions are met. (This will filter all records where ConfigValue < 0 is true, since NULL is not equal to anything).
Related
I need to filter a view in SQL Server Reporting Services (SSRS) with user supplied report parameters, however it should only apply those filters enabled by the user, that is where the report parameter IS NOT NULL.
I'm missing a EVERYTHING_INCLUDING_NULL statement or any other way to completely disable this filter clause.
Furthermore, only the < operator works, the = operator returns "Invalid length parameter passed to the SUBSTRING function".
Any suggestions?
Thanks!
L.
SELECT
*
FROM
[dbo].[my_view]
WHERE
[quantity] = ( CASE WHEN #rp_no_quantity_only = 1 THEN (NULL OR 0) ELSE EVERYTHING_INCLUDING_NULL END)
AND
[prefix] = ( CASE WHEN #rp_prefix IS NOT NULL THEN #rp_prefix ELSE EVERYTHING_INCLUDING_NULL END)
AND
LEFT( [article], CHARINDEX( '-', [article]) - 1) = ( CASE WHEN #rp_article IS NOT NULL THEN #rp_article ELSE EVERYTHING_INCLUDING_NULL END)
AND
[delivery_date] < ( CASE WHEN #rp_delivery_date IS NOT NULL THEN THEN #rp_delivery_date ELSE EVERYTHING_INCLUDING_NULL END)
AND
[invoice_date] < ( CASE WHEN #rp_invoice_date IS NOT NULL THEN #rp_invoice_date ELSE EVERYTHING_INCLUDING_NULL END)
ORDER BY
...
I usually use an OR in each condition to check for the NULL. I checked David's link but it was a little unclear since it was answering a different question. I am a little fuzzy on what you're trying to do with the first condition, but it seems right - it will return only records with a NULL or 0 quantity if #rp_no_quantity_only = 1 otherwise it returns all.
SELECT *
FROM
[dbo].[my_view]
WHERE
(ISNULL([quantity], 0) = IIF(#rp_no_quantity_only = 1, 0, ISNULL([quantity], 0)))
AND
([prefix] = #rp_prefix OR #rp_prefix IS NULL)
AND
(LEFT( [article], CHARINDEX( '-', [article]) - 1) = #rp_article OR #rp_article IS NULL)
AND
([delivery_date] < #rp_delivery_date OR #rp_delivery_date IS NULL)
AND
([invoice_date] < #rp_invoice_date OR #rp_invoice_date IS NULL)
ORDER BY
I've been trying to accomplish something like the code below inside a stored procedure
Select * from TABLE1
CASE WHEN #SPParameter != 0 THEN -- if #SPParameter equals 0 then apply the where condition
WHERE Table1Column = #SPParameter -- apply a where condition
END
This query's goal is to select all rows from TABLE1 if #SPParameter is equal to zero, otherwise filter rows from TABLE1 if #SPParameter is not equal to zero.
Obviously the query above would throw an error message since the syntax is incorrect. Is this possible? Or is an if else statement the only way out?
Just use simple boolean logic1:
Select * from TABLE1
WHERE #SPParameter != 0 OR Table1Column = somevalue
CASE is an expression. It computes a value. It doesn't arbitrarily rearrange the parse tree of the statement it appears in.
1It'll be slightly more complex if we have to deal with NULLs but I've ignored them for now.
You can achieve by using OR condition like this way
WHERE (#SPParameter = 0 OR Table1Column = somevalue)
SELECT Name, JobType
FROM EMP
WHERE 1 = CASE
WHEN JobType = 'VC' THEN 1
WHEN JobType = 'HR' THEN 1
WHEN JobType = 'DEV' THEN 1
ELSE 0
END;
Above example CASE returns if jobtype present in table then it will be return the Name and JobType.
You try using case in where something like below:
Select * from TABLE1
where Table1Column = case when #SPParameter = 0 then #SPParameter else #SPParameter end;
Select * from TABLE1
WHERE Table1Column = CASE
WHEN #SPParameter != 0 THEN #SPParameter
END;
Here WHERE condition gets the value from the CASE statement, if #SPParameter is not equals zero, which means the value is present THEN it will be return the #SPParameter value.
Cant quite figure this one out, i have a set of conditions that i want to be met only if a value is in a field.
So if the Status is complete i want to have three where clause's, if the status doesn't equal complete then i don't want any where clause.
Code
SELECT *
FROM mytable
WHERE CASE WHEN Status = 'Complete'
THEN (included = 0 OR excluded = 0 OR number IS NOT NULL)
ELSE *Do nothing*
It is usually simple to only use boolean expressions in the WHERE. So:
WHERE (Status <> 'Complete') OR
(included = 0 OR excluded = 0 OR number IS NOT NULL)
If Status could be NULL:
WHERE (Status <> 'Complete' OR Status IS NULL) OR
(included = 0 OR excluded = 0 OR number IS NOT NULL)
You can translate the natural language in SQL, then, if possible, reformulate.
SELECT *
FROM mytable
WHERE (Status = 'Complete' and (included = 0 OR excluded = 0 OR number IS NOT NULL))
or status <> 'Complete'
or status IS NULL;
It doesn't look like you really need a CASE statement, just use it like this:
SELECT *
FROM mytable
WHERE where (Status = 'Complete' and (included = 0 OR excluded = 0 OR number IS NOT NULL)) or (*Your do nothing*)
I am using the following query. In this query I want to apply the where clause based on passed parameter. But the issue is that where clause is like 'value = if parameterVal = 'I' than NULL else NOT NULL'
I've build a query like this
SELECT * FROM MASTER
WHERE
Column1 IS (CASE WHEN :Filter = 'I' THEN 'NULL' ELSE 'NOT NULL' END)
but it's not working. Help me solve this.
UPDATE
Updating question to elaborate question more clearly.
I've one table MASTER. Now I am passing one parameter in query that is Filter (indicated by :Filter in query).
Now when the Filter parameter's value is 'I' than it should return the following result.
SELECT * FROM MASTER WHERE Column1 IS NULL
but if the passed argument is not equal to 'I' than,
SELECT * FROM MASTER WHERE Column1 IS NOT NULL
SELECT * FROM MASTER
WHERE (Filter = 'I' AND Column1 IS NULL)
OR
(Filter <> 'I' AND Column1 IS NOT NULL)
If you really insist on using a CASE the SELECT could be rewritten as:
SELECT *
FROM MASTER
WHERE CASE
WHEN COLUMN1 IS NULL AND FILTER = 'I' THEN 1
WHEN COLUMN1 IS NOT NULL AND FILTER <> 'I' THEN 1
ELSE 0
END = 1
SQLFiddle here
Frankly, though, I think that this is very difficult to interpret, and I suggest that #MAli's version is better.
Your case has assignment not equality check
I am trying to add a CASE statement to the end of my SQL query to compute a value depending upon another table value and a previously computed value in the SELECT. The error is returned that DelivCount is an invalid column name. Is there a better way to do this or am I missign something?
SELECT jd.FullJobNumber, jd.ProjectTitle, jd.ClientName, jd.JobManager, jd.ProjectDirector, jd.ServiceGroup, jd.Status, jd.HasDeliverables, jd.SchedOutsideJFlo, jd.ReqCompleteDate,(SELECT COUNT(*)FROM DeliverablesSchedule ds WHERE jd.FullJobNumber = ds.FullJobNumber) as DelivCount, SchedType =
CASE
WHEN (jd.SchedOutsideJFlo = 'Yes')
THEN 'outside'
WHEN (jd.HasDeliverables = 'No ')
THEN 'none'
WHEN (DelivCount > 0)
THEN 'has'
WHEN (jd.HasDeliverables = 'Yes' AND DelivCount = 0)
THEN 'missing'
ELSE 'unknown'
END
FROM JobDetail jd
try this
SELECT
Z.*,
SchedType =
CASE
WHEN (Z.SchedOutsideJFlo = 'Yes')
THEN 'outside'
WHEN (Z.HasDeliverables = 'No ')
THEN 'none'
WHEN (Z.DelivCount > 0)
THEN 'has'
WHEN (Z.HasDeliverables = 'Yes' AND Z.DelivCount = 0)
THEN 'missing'
ELSE 'unknown'
END
FROM
(
SELECT
jd.FullJobNumber,
jd.ProjectTitle,
jd.ClientName,
jd.JobManager,
jd.ProjectDirector,
jd.ServiceGroup,
jd.Status,
jd.HasDeliverables,
jd.SchedOutsideJFlo,
jd.ReqCompleteDate,
(SELECT COUNT(*)FROM DeliverablesSchedule ds WHERE jd.FullJobNumber = ds.FullJobNumber) as DelivCount
FROM JobDetail jd
)
Z
try this, which should run a lot faster:
SELECT
jd.FullJobNumber, jd.ProjectTitle, jd.ClientName, jd.JobManager, jd.ProjectDirector, jd.ServiceGroup, jd.Status, jd.HasDeliverables, jd.SchedOutsideJFlo, jd.ReqCompleteDate
,ds.DelivCount
,SchedType =CASE
WHEN (jd.SchedOutsideJFlo = 'Yes')
THEN 'outside'
WHEN (jd.HasDeliverables = 'No ')
THEN 'none'
WHEN (ds.DelivCount > 0)
THEN 'has'
WHEN (jd.HasDeliverables = 'Yes' AND ds.DelivCount = 0)
THEN 'missing'
ELSE 'unknown'
END
FROM JobDetail jd
LEFT OUTER JOIN (SELECT
FullJobNumber, COUNT(*) AS DelivCount
FROM DeliverablesSchedule
GROUP BY FullJobNumber
) ds ON jd.FullJobNumber = ds.FullJobNumber
The original query uses a subquery:
A subquery is a SELECT query that
returns a single value and is nested
inside a SELECT, INSERT, UPDATE, or
DELETE statement, or inside another
subquery. A subquery can be used
anywhere an expression is allowed.
by the very nature of a sub query, it must be run repeatedly, once for each row. I have rewritten the query to use a derived table, which is evaluated one time to find all of the counts and is then joined to the proper rows. This allows for the DelivCount value to be referred to as any column would be when joined from another table, and should speed up this query.