SQL Using Case in Where clause for null values - sql

I have a SQL query that I am trying to incorporate the possibility of null responses in my selections.
Ultimately, this will end up in a SSRS report.
This query works fine, but any null values in p.ReferralReason will always be returned. I would like the nulls to not be returned if the value of #Reason is anything but '%':
DECLARE #Reason varchar(100)
SET #Reason = 'Lost To Care'
SELECT p.Person_ID, P.Person_Name, p.ReferralReason
FROM VIEW_Patient p
WHERE
p.ReferralReason like '%' + #Reason + '%'
I would like to incorporate all reasons with the #Reason = '%'
If #Reason is set to '%', I would like to include the null values, but I do not want to include the null values if #Reason is set to anything else.
This is what I have tried, but it does not work:
DECLARE #Reason varchar(100)
SET #Reason = '%'
SELECT p.Person_ID, P.Person_Name, p.ReferralReason
FROM VIEW_Patient p
WHERE
case
when #Reason = '%' then (p.ReferralReason like '%' + #Reason + '%' or p.ReferralReason is null)
else p.ReferralReason like '%' + #Reason + '%'
end
MS SQL Server 2008 R2.

If the NULL values are replaced with empty strings they will match patterns consisting entirely of % but not other strings surrounded with %
SELECT p.Person_ID,
P.Person_Name,
p.ReferralReason
FROM VIEW_Patient p
WHERE ISNULL(p.ReferralReason, '') LIKE '%' + #Reason + '%'

Related

SQL ignore condition clause if the value is null or empty

I have the following query
SELECT id, namn, postA, postB postN FROM k.dbo.PF WHERE
namn LIKE #name + '%' AND
postA LIKE #address + '%' AND
postB LIKE #coAddress + '%' AND
postN LIKE #zip + '%' AND
k.dbo.status = 0
This query works as long as I have the correct values in all the fields. But in this case, the care of address (postB column) can sometimes be null in the database. But when I provide the parameter #coAddress with a null value, the query doesn't return anything. How can I rewrite this query so that it will skip the AND clause completely if the coAddress parameter is null?
Use OR:
SELECT id, namn, postA, postB postN
FROM k.dbo.PF
WHERE (#name is null OR namn LIKE #name + '%') AND
(#address is null OR postA LIKE #address + '%') AND
(#coAddress is null OR postB LIKE #coAddress + '%') AND
(#zip is null OR postN LIKE #zip + '%') AND
k.dbo.status = 0;
Try:-
SELECT id, namn, postA, postB postN FROM k.dbo.PF WHERE
namn LIKE #name + '%' AND
postA LIKE #address + '%' AND
(#coAddress is NULL or postB LIKE #coAddress + '%') AND
postN LIKE #zip + '%' AND
k.dbo.status = 0
Any expression involving a NULL value will always return false except for "IS NULL".

SQL - Operator LIKE returns '%' or null

I needs to create a query to the database that will filter the results like this:
[ProjectNumber] LIKE
CASE WHEN IsNull(#ProjectId,'') = '' THEN
'%'
ELSE
#ProjectId + '%'
END
AND
[CountryCode] LIKE
CASE WHEN IsNull(#Country,'') = '' THEN
'%'
ELSE
#Country + '%'
END
When both variables have value everything works, but if #Country is null then this query returns all results for which in the CountryCode column there is a value, and I need to return all (even if the field is Null). Anyone know how to write this query in case of null variable that returned all the fields (fields with value and fields with null)?
Instead of using CASE ... WHEN ... and ISNULL function, you can do this:
...
(#ProjectId IS NULL OR [ProjectNumber] LIKE #ProjectId + '%')
AND
(#Country IS NULL OR [CountryCode] LIKE #Country + '%')
...
You need to simply use
ProjectNumber LIKE IsNull(#ProjectId,'') + '%' AND
CountryCode LIKE IsNull(#Country,'') + '%'
You don't need to use the case statement. Try the below :
ISNULL([ProjectNumber],'') LIKE IsNull(#ProjectId,'')+'%'
AND
ISNULL([CountryCode],'') LIKE ISNULL(#Country,'') + '%'
because both your case statements will give the same effect above.

How to make my search for multiple columns procedure more efficient?

I have a stored procedure that searches across multiple columns in a combined table.
It works, however, it takes 15 seconds to search for a value in that combined table. The table takes 9 seconds to load so I'm not sure, maybe it's because my table too big?
So I'm just wondering if there's a way to make this query runs faster.
This is my stored procedure:
create procedure LRMWEB_Search
#input nvarchar(1500)
AS
SET NOCOUNT ON;
SELECT tr.ResourceID ,
tr.ProjectFile,
tr.ResourceFile,
tr.ResourceName,
trt.Culture,
trt.TranslatedFlag,
trt.TranslatedValue,
tr.Comments,
tr.IsApproved
FROM tblResourcesTranslated_NEW trt
INNER JOIN tblResources_NEW tr ON trt.ResourceID = tr.ResourceID
where tr.ResourceID like '%'+ #input + '%'
OR tr.ProjectFile like '%'+ #input + '%'
OR tr.ResourceFile like '%'+ #input + '%'
OR tr.ResourceName like '%'+ #input + '%'
OR tr.ResourceValue like '%'+ #input + '%'
OR tr.Comments like '%'+ #input + '%'
OR trt.Uid like '%'+ #input + '%'
OR trt.TranslatedValue like '%'+ #input + '%'
;
Any use of like precludes an index, unless it has a fixed prefix with a wildcard suffix, such as where foo like 'bar%'. Your like expressions (e.g., '%xxx%' ) do not meet that requirement.
As a result, while the join criteria may well have a covering index, nothing else does and so a table scan of the join tables is required.
In a nutshell, there is no way to fix performance outside of either
rethinking what you're doing, or
using something like a full text search
SELECT tblResources_NEW.ResourceID
,tblResources_NEW.ProjectFile
,tblResources_NEW.ResourceFile
,tblResources_NEW.ResourceName
,tblResourcesTranslated_NEW.Culture
,tblResourcesTranslated_NEW.TranslatedFlag
,tblResourcesTranslated_NEW.TranslatedValue
,tblResources_NEW.Comments
,tblResources_NEW.IsApproved
FROM
(
SELECT
tblResources_NEW.ResourceID
,tblResources_NEW.ProjectFile
,tblResources_NEW.ResourceFile
,tblResources_NEW.ResourceName
,tblResources_NEW.Comments
,tblResources_NEW.IsApproved
FROM tblResources_NEW
WHERE
tblResources_NEW.ResourceID like '%'+ #input + '%'
OR tblResources_NEW.ProjectFile like '%'+ #input + '%'
OR tblResources_NEW.ResourceFile like '%'+ #input + '%'
OR tblResources_NEW.ResourceName like '%'+ #input + '%'
OR tblResources_NEW.ResourceValue like '%'+ #input + '%'
OR tblResources_NEW.Comments like '%'+ #input + '%'
) AS tblResources_NEW
INNER JOIN
(
SELECT
tblResourcesTranslated_NEW.ResourceID
,tblResourcesTranslated_NEW.Culture
,tblResourcesTranslated_NEW.TranslatedFlag
,tblResourcesTranslated_NEW.TranslatedValue
FROM tblResourcesTranslated_NEW
WHERE
tblResourcesTranslated_NEW.Uid like '%'+ #input + '%'
OR tblResourcesTranslated_NEW.TranslatedValue like '%'+ #input + '%'
) AS tblResourcesTranslated_NEW ON tblResourcesTranslated_NEW.ResourceID=tblResources_NEW.ResourceID
If You insist on having one input for all fields, I would at least boost some performance by doing dynamic SQL.
Alter PROCEDURE LRMWEB_Search
(
#input nvarchar(1500)
)
AS
declare #sql varchar(2000);
SET NOCOUNT ON;
set #sql = 'SELECT
tblResources_NEW.ResourceID,
tblResources_NEW.ProjectFile,
tblResources_NEW.ResourceFile,
tblResources_NEW.ResourceName,
tblResourcesTranslated_NEW.Culture,
tblResourcesTranslated_NEW.TranslatedFlag,
tblResourcesTranslated_NEW.TranslatedValue,
tblResources_NEW.Comments,
tblResources_NEW.IsApproved
FROM
tblResourcesTranslated_NEW INNER JOIN
tblResources_NEW ON tblResourcesTranslated_NEW.ResourceID=tblResources_NEW.ResourceID
where ';
-- here I would concatenate all your string conditions
if (ISNUMERIC(#input)= 0)
Begin
. . . . . . .
End
-- here I would concatenate all your numeric conditions
if (ISNUMERIC(#input)= 1)
Begin
set #sql = #sql + ' OR tblResources_NEW.ResourceID like ''%#1%''';
. . . . .
End
-- call to execute
EXECUTE sp_executesql #sql, N'#1 varchar', #1 = #input;
This should give you at least some boost by excluding unneeded searches. But really, you should do something like this by using single parameter for every condition. Than you can exclude those that are Null from building into string.
But, again, this design is BAD.

Adding a WHERE statement to an SQL query based on an IF statement

Issue: I only want to filter the PropertySearch value if there is one
I want to be able to have a dynamic SQL statement based on this.
I have added If #PropertySearch which filters from a textbox on the webform.
The search works up to -- If #PropertySearch <> '' -- and will work if I comment the code
--
If #PropertySearch <> ''
BEGIN
TblA.PropertyID LIKE '%' + #PropertySearch + '%' OR TblA.Propertyname LIKE '%' + #PropertySearch +' %'
END
--
I want to only filter the PropertyID/PropertySearch when there is a #PropertySearch.
I have looked at having 'AND' after 'BEGIN' as well as Nested tables but am struggling
If #RegionID = 1 --then -- Head office users
BEGIN
SELECT TblA.PropertyID as PId, TblA.Propertyname as PNa, TblB.FireSafetyDisplay as FireSafety1, TblB.SlipsandTripsDisplay as SaT
FROM TbPropertyDetails as TblA inner join TbPropertyDetailsSafeguarding as TblB on TblA.PropertyID = TblB.PropertyID
WHERE TblA.RegionID > 0
If #PropertySearch <> ''
BEGIN
TblA.PropertyID LIKE '%' + #PropertySearch + '%' OR TblA.Propertyname LIKE '%' + #PropertySearch +' %'
END
END
WHERE TblA.RegionID > 0 AND (#PropertySearch = ''
OR TblA.PropertyID LIKE '%' + #PropertySearch + '%' OR TblA.Propertyname LIKE '%' + #PropertySearch +' %')

T-SQL: CASE statement in WHERE?

I have the following WHERE clause in my SQL query currently:
WHERE c.Town LIKE '%' + #Town + '%'
What I want do is make the first '%' optional - so if the user has selected to just filter by records that just start with the given text, the WHERE would be
WHERE c.Town LIKE #Town + '%'
I assumed the simplest way to do this would be CASE statements, but I'm having no joy as it seems the syntax is incorrect. Can I get any pointers? Here's the CASE statement I was trying:
WHERE c.Town LIKE (CASE WHEN #FilterOptions = 1 THEN '%' ELSE '') + #Town + '%'
You missed the END:
WHERE c.Town LIKE (CASE WHEN #FilterOptions = 1 THEN '%' ELSE '' END) + #Town + '%'
A CASE must end with an END. Try
WHERE c.Town LIKE (CASE WHEN #FilterOptions = 1 THEN '%' ELSE '' END) + #Town + '%'
Case should have end.
I think the below statement can help you.
WHERE c.Town LIKE (CASE WHEN #FilterOptions = 1 THEN '%' ELSE '' END) + #Town + '%