Use IF conditional into where clause - sql

I have a query where I want to use something like IF conditional into WHERE clause so I do something like:
...
AND (#City = '%'
OR [a].[City] LIKE(#City))
So I read this like : IF #City = '%' just continue , if not execute OR clause OR [a].[City] LIKE(#City)
But when I run code results don't return values as I want. What am I doing wrong? am I reading this wrong?

You should be able to simply do:
WHERE . . . AND
[a].[City] LIKE #City
% is the wildcard for LIKE, so CITY LIKE '%' returns all non-NULL values of CITY. This seems to be the intention of using '%' for selecting all cities.

try like below:
...
AND (#City = '%'
OR [a].[City] LIKE('%'+ #City + '%'))

try this on your where clause:
WHERE #City = '%' OR [a].[City] LIKE '%' + #City + '%'

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.

SQL Using Case in Where clause for null values

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 + '%'

Using LIKE within CASE in TSQL

I would like to select the records that contain the content of the #selctDescription parameter but only when #selctDescription is not empty.
I have the following, which does not work:
(t.[description] LIKE
(
CASE
WHEN #selctDescription = '' THEN t.[description]
ELSE ('%' #selctDescription '%')
END
)
)
Can anyone point me in the right direction?
SELECT *
FROM Table
WHERE
((#selctDescription IS NULL OR #selctDescription = '')
OR
(t.[description] LIKE '%' + #selctDescription +'%'))
#selctDescription = '' OR t.[description] LIKE '%' + #selctDescription + '%'
I think your code is equivalent to:
t.[description] LIKE '%' + #selctDescription + '%'
Your description on the other hand, suggests you want this:
#selctDescription <> ''
AND t.[description] LIKE '%' + #selctDescription + '%'
A couple of thoughts for you...
Where you have '%' #selctDescription '%', you just need + between the strings to concatenate them. Your code will then work as is.
'%' + #selctDescription + '%'
Also, it's useful to note that you don't even need the CASE statement, as when the parameter is blank, you get '%%', which will still match everything.
This is useful to know because at present you have table fields on both sides of the LIKE statement. This will really hurt the optimiser. If I were to use CASE I'd be more tempted to stick to...
t.[description] LIKE (CASE WHEN #selctDescription = '' THEN '%' ELSE ('%' + #selctDescription + '%') END)
This has the benefit that the result of the CASE statement can be performed once, as a scalar value, prior to execution of the query. As opposed to being recalculated ever row.
And that said, it then becomes functionally identical to...
t.[description] LIKE ('%' + #selctDescription + '%')
Based on your first line and comments, you need to make the following select:
Select * from table
where field <> ''
and field like '%' + #selctDescription + '%'
But you must put the correct table and field and #selctDesciption must be text (char, nchar, varchar, nvarchar, ...).