SQL problem with multi field searches - sql

I am having some problems here, I have actually had the same issue for a while now but I hack around and get it working in the end however I would like to know if I have missed a simple way of doing it.
Say if I have:
Field input 1
Field input 2
Field input 3 (empty)
Field input 4
I want to query SELECT * FROM tbl_table WHERE field1 LIKE ? AND field2 LIKE ? AND field3 LIKE ? AND field4 LIKE ?
Basically I come into trouble when an input is empty because its searching in a field and looking for null or another string when I want it to just discard the LIKE operator of the empty Input.
I know this might read really bad however its hard to get a point across some times.

SELECT * FROM tbl_table WHERE (field1 IS NULL OR field1 LIKE ?) AND (field2 IS NULL OR field2 LIKE ?) AND ....

Essentially, you need to check the value of the variable in the where clause. Check if it is null or has value like this.
Declare #input1 varchar(50);
Declare #input2 varchar(50);
Declare #input3 varchar(50);
Declare #input4 varchar(50);
SET #input1 = 'a'
SET #input2 = 'b'
SET #input3 = NULL
SET #input4 = 'c'
SELECT
*
FROM tbl_table
WHERE
(#input1 is null OR field1 LIKE #input1)
AND (#input2 is null OR field1 LIKE #input2)
AND (#input3 is null OR field1 LIKE #input3)
AND (#input4 is null OR field1 LIKE #input4)

Related

Using the LIKE operator and "greater than" in a Case When expression

This is for a section in a unit test that I'm writing.
I am trying to say pass if any row in a column contains a certain string. So in words, what I want is "if the number of row that contain astring is greater than zero than pass the test".
I have something like the code below, but it fails saying that myVariable needs to be declared. What am I doing wrong?
DECLARE #myVariable BIT =
(
SELECT CASE
WHEN Count(Description) LIKE '%astring%' > 0
THEN
1
ELSE
0
END
FROM TABLE
SELECT #myVariable
I think you want:
DECLARE #myVariable BIT =
(SELECT (CASE WHEN Count(*) > 0 THEN 1 ELSE 0 END)
FROM TABLE
WHERE Description LIKE '%astring%'
);
I wouldn't recommend a bit for this. SQL Server doesn't really support booleans. Integers (or tinyints even) are usually easier to work with than bits.
Just:
DECLARE #myVariable BIT = (
SELECT MAX(CASE WHEN Description LIKE '%astring%' THEN 1 ELSE 0 END)
FROM mytable
);
This sets the variable to 1 if at least one row in the table has a Description that matches the pattern.
DECLARE #myVariable BIT=
(
SELECT IIF(ISNULL(count(*),0)>0,1,0)
FROM TABLE
WHERE EXISTS(SELECT * FROM TABLE WHERE Description LIKE '%astring%')
)
SELECT #myVariable AS myVariable

How to check a comma delimited integer values by "IF" condition T-SQL?

A simple table contains the one column with integer vales.The Figure is given below.
I am using COALESCE to construct the 'numbers' by comma.
So, now there is a problem when i check a above constructed value in IF Condition like below. It shows an error for cannot convert the varchar datatype to integer.
Now how to check the constructed values in IF condition without changing a logic? I am new for T-SQL.Thank you
When you concatenate all the numbers you are converting it a string so it no longer acts like an integer. If you want to check for a value in a list, do it directly like. SQL was made to have different values in different rows and work with them that way. Try this out:
DECLARE #failIds INT = 23;
IF #failIds IN (SELECT numbers FROM model)
BEGIN
PRINT 'YES'
END
ELSE
BEGIN
PRINT 'NO'
END
Instead of the comma separated string, you should use a table variable, temp. table or just the original table. For example, something like this:
declare #Ids table (id int)
insert into #Ids
select numbers
from model
where numbers in (23,234)
declare #failIds int = 23
if (exists (select 1 from #Ids where id = #failIds)) begin
print 'Yes'
end else begin
print 'No'
end
But you could of course do this too:
if (exists (select 1 from model where numbers = #failIds)) begin
print 'Yes'
end else begin
print 'No'
end
I am very lazy to think about it, Finally i get answer like give below. Its very simple.

Dynamic WHERE clause in T-SQL

I have a requirement to display reports if a field value or a combination of field value matches.
I have designed a table to store ReportId values against a field or a combination of fields. I have stored the values in a pattern so that I can construct the WHERE clause for SQL to fetch desired data. Following is the table data:
Field1 Field2 Field3 ReportId
2 NULL NULL Rep1
5 4 NULL Rep2
6 NULL 8 Rep4
Now, I want to create a stored procedure to fetch relevant ReportIds. In the stored procedure I have following parameters as input:
Parameter1, Parameter2, Parameter3
In the stored procedure, I want to construct a SQL with a dynamic WHERE clause to fetch ReportIds. The WHERE clause will put a AND operator between all NON NULL fields and compare with the passed parameters.
As per the given table data, the non-null field in first row is “Field1”. So the WHERE clause will be
Field1 = Parameter1
As per the given table data, the non-null fields in the second row is “Field1” and “Field2”. So WHERE clause will be:
Field1 = Parameter1 AND Field2 =Parameter2
As per the given table data, the non-null fields in the third row is “Field1” and “Field3”. So the WHERE clause will be:
Field1 = Parameter1 AND Field3 =Parameter3
How I can write a generic SQL with a dynamic WHERE clause for this requirement?
Le sigh.
The solution I am thinking of is a simple:
WHERE (Field1 IS NULL OR Field1=#Parameter1)
AND (Field2 IS NULL OR Field2=#Parameter2)
AND ...
You can stack any number of field/parameter pairings into this solution.
You can construct the query by appending the where clause to NVARCHAR(MAX) variable and then execute that query with sql built in function sp_executesql
For Example
DECLARE #query NVARCHAR(MAX);
SET #query = 'SELECT #Count = COUNT(*) FROM Reports WHERE 1=1 '
IF #Field1 IS NOT NULL
SET #query = #query + 'AND Field1 = #Field1 '
......
......
......
EXECUTE sp_executesql #query,
N'#Field1 VARCHAR(MAX),
....
....
#Param1,
.....
.....
I hope this helps you get the right direction.
If you think about what you are looking for and restate your question it becomes easier. What do you really want to do? You want to include rows where each field matches the parameter passed, or whether the value in the table is null. So you want to match rows where each field is either null, or it matches the parameter:
WHERE (Field1 is null OR Field1 = #Parameter1)
AND (Field2 is null OR Field2 = #Parameter2)
AND (Field3 is null OR Field3 = #Parameter2)

CASE WHEN in WHERE with LIKE condition instead of 1

I have a query with a bunch of OR's inside an AND in the where clause and I'm trying to replace them with CASE WHEN to see if it improves the performance.
The select query inside the stored procedure is something like:
DECLARE #word = '%word%' --These are inputs
DECLARE #type = 'type'
SELECT * FROM table1
WHERE SomeCondition1
AND ( (#type = 'CS' AND col1 like #word)
OR
(#type = 'ED' AND col2 like #word)
....
)
I'm trying to write this query as:
SELECT * FROM table1
WHERE SomeCondition1
AND ( 1= CASE WHEN #type = 'CS'
THEN col1 like #word
WHEN #type = 'ED'
THEN col2 like #word
END )
But SQL 2012 gives the error 'Incorrect Syntax Near Like' for THEN col1 like #word. If I replace THEN col1 like #word with 1 then no complaints but LIKE should return a 0 or 1 anyway.
I tried SELECT (col1 like #word), extra (), etc with no success.
Is there a way to include LIKE in CASE WHEN in WHERE or should I just not bother if using CASE WHEN instead of the original IF's won't make any performance difference?
UPDATE:
This actually didn't make any difference performance wise.
There are is a lot of info online about these 'optional' type stored procedures and how to avoid parameter sniffing performance issues.
This syntax should get you closer though:
AND CASE
WHEN #type = 'CS' THEN col1
WHEN #type = 'ED' THEN col2
END LIKE #word
Just make sure the col1 and col2 datatypes are similar (don't mix INT and VARCHAR)
You should compare query plans between the two syntaxes to ascertain whether it even makes a difference. Your performance issue might be due more to parameter sniffing.
You can also try nested case statements. e.g. based on your latest post, something like:
1 = CASE WHEN #type = 'CandidateStatus'
THEN (CASE WHEN co.[Description] LIKE #text THEN 1 END)
...
END
Here's how I got it to work, now just need to test if it makes any difference to performance. #Nick.McDermaid 's parameter sniffing is worth looking at.
1 = CASE WHEN #type = 'CandidateStatus'
THEN (SELECT 1 WHERE co.[Description] LIKE #text)

If parameter is null, pull results from table

This might be a stupid question, but I haven't found a way to word this to get an answer that suits what I'm trying to accomplish. I might just be having a stupid moment.
I have an input variable for a sproc; that input variable may be passed in as null.
If the value is null, I would like insert into a temp table a list of values from another table. Otherwise, I'd just like to insert into the temple table the value of the parameter.
What I'm trying to do is something like this
INSERT INTO #tempTable
SELECT (CASE WHEN #myVariable IS NULL
THEN (SELECT [myVariable] FROM myTable)
ELSE #myVariable END)
This won't work because that select statement pulls back a large number of results (and it's malformed), but that's the general idea. I basically want to have an optional parameter where the user can specify a specific ID, or get back ALL the IDs.
Does anyone have any suggestions on the best way to go about this?
Thank you!
I think this UNION will do
INSERT INTO #tempTable
SELECT #myVariable WHERE #myVariable IS NOT NULL
UNION
SELECT [myVariable] FROM myTable WHERE #myVariable IS NULL
Of course if it doesn't need to be one query - you can use simple IF logic
IF #myVariable IS NULL
INSERT INTO #tempTable
SELECT [myVariable] FROM myTable
ELSE
INSERT INTO #tempTable
SELECT #myVariable
Would something like this work for you?
SELECT DISTINCT ISNULL(#myVariable, myVariableColumn)
FROM myTable
I suggest this query:
INSERT INTO #tempTable
SELECT CASE WHEN #myVariable IS NULL Then [myVariable] else #myVariable end FROM myTable