How do I add conditional statements to test for a specific value in dynamic where clause in stored procedure - sql

I have a stored procedure into which I pass a number of variables and I create a dynamic where clause using the "AND (#var IS NULL OR table.field = #var)" and it works great... EXCEPT
One of the variables (#statusLevel) can be either 1-9 or 10. When the value passed in is 10, I want to return ONLY those projects that have a statusLevel = 10. When the value passed in is between 1 & 9, I want to return all of the projects between that value (let's say '5') and less than 10.
I've got each part working perfectly independently but I'm lost on how to get them to work together.
AND ((#statusLevelID IS NULL OR project.statusLevelID >= #statusLevelID) AND (#statusLevelID IS NULL OR project.statusLevelID < 10))
AND (#statusLevelID IS NULL OR project.statusLevelID = 10)
Using an "OR" just gives me ALL of the projects.
AND ((#statusLevelID IS NULL OR project.statusLevelID >= #statusLevelID) AND (#statusLevelID IS NULL OR project.statusLevelID < 10)
OR (#statusLevelID IS NULL OR project.statusLevelID = 10))
I was thinking a CASE statement might work here but I'm not exactly sure how to implement that.
Any assistance is greatly appreciated. Thanks in advance.

You want one boolean expression connected by ORs:
AND ( (#statusLevelID IS NULL) OR
(#statusLevelID = project.statusLevelID) OR
(#statusLevelID <> 10 AND project.statusLevelID >= #statusLevelID AND project.statusLevelID < 10)
)

You can write the condition like so:
AND (
#statusLevelID IS NULL
OR
project.statusLevelID BETWEEN #statusLevelID AND IIF(#statusLevelID = 10, 10, 9)
)

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.

CASE Expression within WHERE clause for different date fields

I'm trying to include a case expression within a where clause, to show all records depending on two forms of criteria. I'm getting lots of syntax errors with the below and wondering what I'm missing?
...
AND
CASE WHEN (TypeName = 'Category1' or TypeName = 'Category2') THEN
Headers.HeaderDate < DATEADD(dd,1,#ReportDate)
ELSE
Headers.TimeStamp < DATEADD(dd,1,#ReportDate)
END
Case is an expression not a statement and as such returns a value, not a condition, so you want
AND CASE WHEN (TypeName = 'Category1' OR TypeName = 'Category2')
THEN Headers.HeaderDate ELSE Headers.TimeStamp END < DATEADD(dd,1,#ReportDate)
There is a way to do it without using a case expression
and (
(Typename in ('Category1','Category2') and Headers.HeaderDate < DATEADD(dd,1,#ReportDate)
or (Typename not in ('Category1','Category2') and Headers.TimeStamp < DATEADD(dd,1,#ReportDate)
)
If Typename can be null you should also keep it in mind.

Adding with NULL in SQL

i'm planning to add sql values.
Dim cmdStringc23 As String = " Update [Associate_wise_chart]
set [Hours]= (select SUM(tat) from [Dashboard].[dbo].[Dashboard]
where [assignee] like '%Santosh%') + (select SUM(tat)
from [Dashboard].[dbo].[requests]
where [assignee] like '%Santosh%') "
So consider,
value from dashboard table is 10
value from requests table is NULL.
So I'm getting answer as 10+NULL = NULL.
I have set tat as NULL. My requirement , i have to display answer as 10 and not as NULL
Could any one have a look ?
Use ISNULL function from SQL ...
Update [Associate_wise_chart]
set [Hours]= ISNULL((select SUM(tat) from [Dashboard].[dbo].[Dashboard]
where [assignee] like '%Santosh%'), 0) + ISNULL((select SUM(tat)
from [Dashboard].[dbo].[requests]
where [assignee] like '%Santosh%'), 0) "
That will get you ISNULL(10, 0) + ISNULL(NULL, 0) = 10 + 0 = 10
You can't.
NULL is a synonym for "unknown". Ten plus unknown is unknown. The unknown can be 0, -1, 42, or even 6E23+π/2. But it's still unknown.
This is why you get NULL.
Instead, check for NULLs, and only add the other value, if it is not NULL.
set NOTNULL while creating the table
fast and easy just convert tat column into Not Null and have 0 in place of NULL.
Dim cmdStringc23 As String = " Update [Associate_wise_chart]
set [Hours]= (select isnull(sum(tat), 0) from [Dashboard].[dbo].[Dashboard]
where [assignee] like '%Santosh%') + (select isnull(sum(tat), 0)
from [Dashboard].[dbo].[requests]
where [assignee] like '%Santosh%') "
Use isnull
Update [Dashboard].[dbo].[Associate_wise_chart]
set [Hours]= ISNULL ( (select SUM(tat) from [Dashboard].[dbo].[Dashboard] where [assignee] like '%Santosh%'),0) + ISNULL((select SUM(tat) from [Dashboard].[dbo].Unbuilds where [assignee] like '%Santosh%'),0) where [Name]='Santhosh'
ISNULL is working. Thank you Everyone.

WHERE [Expression] = TRUE/FALSE in SQL Server

I have a situation where I'm trying to filter people that have credits or not. Here's an example Dapper query for reference:
var sql = #"
SELECT *
FROM Person
WHERE (Person.Credits > 0) = #hasCredits";
Connection.Query(sql, new { hasCredits });
I was pretty sure Postgres allows you to do this, hence my surprise when on SQL Server this failed with Incorrect syntax near '='.
With the sample data below, I would expect the query to return the Person with the ID of 1 when hasCredits is FALSE and the Person with the ID of 2 when hasCredits is TRUE.
INSERT INTO Person (PersonId, Credits) VALUES (1, 0), (2, 0);
In SQL Server Is there a way to evaluate whether an expression evaluates to true or false?
I've considered the following (horrible looking) options, but was hoping there was a more elegant solution:
"WHERE (Person.Credits " + (hasCredits ? ">" : "=") + " 0)"
"WHERE (#hasCredits = 1 AND Person.Credits > 0) OR (#hasCredits = 0 AND Person.Credits = 0)"
Considering that when Has credits radio button is selected #hasCredits variable will have 1 else when Doesn't have credits is selected #hasCredits variable will have 0 else #hasCredits variable will be null
SELECT *
FROM Person
WHERE (Person.Credits > 0 and #hasCredits=1) or --Has credits
(Person.Credits <1 and #hasCredits=0) or --Doesn't have credits
(#hasCredits IS NULL) --Don't care
You question was quite plain and the answer is super easy!
case when Person.Credit > 0 then 1 else 0 end = #hasCredits