CASE statement after WHERE then one of several values can be NULL? - mysql

I have such select:
SELECT
*
FROM
Table Tb
WHERE
Tb.LastModificationDate BETWEEN #StartDate And #EndDate
AND Tb.var1 = #var1
AND Tb.var2 = #var2
And its possible that #var1 and #var2 can be null (or only one of them) so for now I have 3 selects for each case (real select is more complicated so I am providing example for simplify things) I am try to merge them into one select with CASE but have no luck so far - as cant understand how to include AND clause in case if one of vars are not null.
I believe it should be something like that:
SELECT
*
FROM
Table Tb
WHERE
Tb.LastModificationDate BETWEEN #StartDate And #EndDate
(CASE WHEN #var1 IS NOT NULL THEN (AND Tb.var1 = #var1)
WHEN #var2 IS NOT NULL THEN (AND Tb.var2 = #var2)
END);
any advice on that?

To use the CASE statement, you would need to remove the AND clause from the THEN portion and move it to outside of CASE so that the result is evaluated. This is because CASE can not append the criteria to the WHERE clause (THEN AND).
SELECT *
FROM Table Tb
WHERE Tb.LastModificationDate BETWEEN #StartDate And #EndDate
AND (CASE
WHEN #var1 IS NOT NULL THEN Tb.var1 = #var1
WHEN #var2 IS NOT NULL THEN Tb.var2 = #var2
END);
However, the above approach will be limited to the first "CASE #var* IS NOT NULL" that evaluates as true. So if both #var1 and #var2 are supplied, the CASE will only return Tb.var1 = #var1, and will not compare Tb.var2 = #var2.To retrieve a result when both #var1 and #var2 are NULL, ELSE true would need to added to the CASE statement.
(CASE
WHEN #var1 IS NOT NULL THEN Tb.var1 = #var1
WHEN #var2 IS NOT NULL THEN Tb.var2 = #var2
ELSE true
END);
Another approach that circumvents the first case limitation, would be to apply the criteria directly to the WHERE clause by using AND (IS NULL OR ...).
This will allow for the criteria to match under the following 4 conditions:
Not checked if both #var1 and #var2 are NULL
#var1 if supplied (Tb.var1 = #var1)
#var2 if supplied (Tb.var2 = #var2)
#var1 and #var2 if both are supplied (Tb.var1 = #var1 AND Tb.var2 = #var2)
SELECT *
FROM Table Tb
WHERE Tb.LastModificationDate BETWEEN #StartDate And #EndDate
AND (#var1 IS NULL OR Tb.var1 = #var1)
AND (#var2 IS NULL OR Tb.var2 = #var2);
Working Examples: DB-Fiddle

SELECT
*
FROM
Table Tb
WHERE
Tb.LastModificationDate BETWEEN #StartDate And #EndDate
AND ((#var1 IS NOT NULL AND Tb.var1 = #var1)
OR
(#var2 IS NOT NULL AND Tb.var2 = #var2));
I would have done this way.

Check for both #var1 and #var2 if they are NULL or equal to the value of a column:
WHERE Tb.LastModificationDate BETWEEN #StartDate And #EndDate
AND (#var1 IS NULL OR Tb.var1 = #var1)
AND (#var2 IS NULL OR Tb.var2 = #var2)

Related

MySql select statement with conditional where clause

I am trying to write a MySql statement with a conditional where clause.
something like this:
set #price = 5000 ;
set #city = 1324368075;
select count(*)
from property
where case when #price is not null then
price < #price
end
and (case when #city is not null then
CityId = #city
end)
the variable should be included in the query only if it is not null.
My attempts have failed so far. Any ideas?
Edited:
Sorry I spoke too soon ysth,
these two queries are supposed to yield the same count but they dont.
Edit #2: Execution plan & indexes
Here's the query:
set #CountryId = null ;
set #CityId = 1324368075 ;
set #StateProvince = null ;
set #CategoryId = null ;
set #TransactionTypeId = null;
set #Price = 5000;
SELECT
Count(*)
FROM
meerkat.property
WHERE
(CASE WHEN #CountryId IS NOT NULL THEN CountryId = #CountryId ELSE 1 END)
AND (CASE WHEN #CityId IS NOT NULL THEN CityId = #CityId ELSE 1 END)
AND (CASE WHEN #CategoryId IS NOT NULL THEN CategoryId = #CategoryId ELSE 1 END)
AND (CASE WHEN #StateProvince IS NOT NULL THEN StateProvince = #StateProvince ELSE 1 END)
AND (CASE WHEN #TransactionTypeId IS NOT NULL THEN TransactionTypeId = #TransactionTypeId ELSE 1 END)
AND (CASE WHEN #Price IS NOT NULL THEN Price <= #Price ELSE 1 END)
AND IsPublic = 1
AND IsBlocked = 0;
Thanks in advance
If no when conditions are met, case returns null. If you want each test to pass, you need to return a true value instead, so:
case when #price is not null then
price < #price
else 1 end
and ...

Set a variable inside case statement in mysql

I have the following scenario
SELECT
...
...
(
#var1 = MAX(IF(table1.name='Mod', table1.value, NULL))
#var2 = MAX(IF(table1.name='Man', table1.value, NULL))
CASE
WHEN #var1 IS NOT NULL && #var2 IS NOT NULL THEN #var1+"/"+#var2
WHEN #var1 IS NULL && #var2 IS NOT NULL THEN #var2
WHEN #var1 IS NOT NULL && #var2 IS NULL THEN #var1
ELSE NULL
END) AS "col44",
This is throwing me an exception in the mysql console.
Can't we do a variable assignment in the general mysql select query?
What about this?
SELECT ...
, #var1 = MAX(IF(table1.name='Mod', table1.value, NULL))
, #var2 = MAX(IF(table1.name='Man', table1.value, NULL))
, CASE
WHEN #var1 IS NOT NULL && #var2 IS NOT NULL THEN #var1+"/"+#var2
WHEN #var1 IS NULL && #var2 IS NOT NULL THEN #var2
WHEN #var1 IS NOT NULL && #var2 IS NULL THEN #var1
ELSE NULL
END AS "col44"
Note the addition of commas, and removal of parenthesis.
Alternatively, you could just use a subquery. (In my experience, variables in queries can become unpredictable when used in conjunction with aggregation; this avoids the variables altogether).
SELECT ...
, CASE
WHEN modMax IS NOT NULL && manMax IS NOT NULL THEN modMax+"/"+manMax
WHEN modMax IS NULL && manMax IS NOT NULL THEN manMax
WHEN modMax IS NOT NULL && manMax IS NULL THEN modMax
ELSE NULL
END AS "col44"
FROM (
SELECT ...
, MAX(IF(table1.name='Mod', table1.value, NULL)) AS modMax
, MAX(IF(table1.name='Man', table1.value, NULL)) AS manMax
...
) AS subQ
Additional note: Watch out for modMax+"/"+manMax; it may end up giving you an integer calculated from modMax+0+manMax, instead of a string.

Use multiple variables in select

I have a question about using variables.
I need to get different values from the same condition.
Is the following example correct?
Many thanks!!!!
DECLARE #var1 varchar(50)
DECLARE #var2 varchar(50)
SELECT #var1, #var2
FROM table
WHERE IF condicion1 IN (1, 2, 3)
BEGIN
SET #var1='Value1'
SET #var2='Value2'
END
You can assign values to variables in SELECT statement.
DECLARE #var1 varchar(50)
DECLARE #var2 varchar(50)
SELECT #var1 = CASE WHEN condicion1 = 1 THEN 'Value1'
WHEN condicion1 = 2 THEN 'Value1'
WHEN condicion1 = 3 THEN 'Value1' END,
#var2 = CASE WHEN condicion1 = 1 THEN 'Value2'
WHEN condicion1 = 2 THEN 'Value2'
WHEN condicion1 = 3 THEN 'Value2' END
FROM table

Issue with include/exclude data in my stored procedure depending of parameter

I had an issue in my stored procedure that needs to include rows or not depending on the value of a parameter
if #var_exclude = 'Y' I need to show only rows that mytable.field1 = 'N'
if #var_exclude = 'N' I need to show all rows
I'm using the following query but doesn't work properly
My code is like
#var_exclude varchar(1)
select mytable.field1, mytable.field2, mytable.field3, mytable.field4,mytable.field5
from mytable
Where mytable.field6 is null
and mytable.field1 is not null
and (mytable.state = #paramstate or #paramstate = 'ALL')
and mytable.field1 = Case when #var_exclude= 'Y' Then 'N' Else #var_exclude End
End
I'm confused!
Your logic handling #var_exclude is wrong.
When you pass #var_exclude = 'Y', then your query basically gets resolved to:
select .....
from mytable
where mytable.field6 is null
and mytable.field1 is not null
and (mytable.state = #paramstate or #paramstate = 'ALL')
and mytable.field1 = 'N'
since in this case, the when #var_exclude= 'Y' Then 'N' part of your CASE clause is used.
If you pass anything else in, then you take the value you're passing in; so if you pass in #var_exclude = 'N' then your query is resolved to:
select .....
from mytable
where mytable.field6 is null
and mytable.field1 is not null
and (mytable.state = #paramstate or #paramstate = 'ALL')
and mytable.field1 = 'N'
since in this case the Else #var_exclude of your CASE clause is used - and since #var_exclude = 'N', you get the exact same query as before....
I would probably write this procedure something like this:
CREATE PROCEDURE dbo.GetData
#paramstate VARCHAR(???),
#var_exclude CHAR(1)
AS BEGIN
IF #var_exclude = 'N' THEN
SELECT
t.field1, t.field2, t.field3, t.field4, t.field5
FROM
dbo.mytable t
WHERE
t.field6 IS NULL
AND t.field1 IS NOT NULL
AND (t.state = #paramstate OR #paramstate = 'ALL')
ELSE
SELECT
t.field1, t.field2, t.field3, t.field4, t.field5
FROM
dbo.mytable t
WHERE
t.field6 IS NULL
AND t.field1 IS NOT NULL
AND (t.state = #paramstate OR #paramstate = 'ALL')
AND t.field1 = 'N'
END
Hey in case anyone is still looking for something like this, you CAN actually do it in the where clause, you need to write an IN statement and evaluate the condition as follows:
DECLARE #Include bit
SELECT ISNULL(CASE #Include WHEN 1 THEN 1 END,0)
UNION
SELECT ISNULL(CASE #Include WHEN 1 THEN 0 END,0)
So this will evaluate to:
IF #Include = 1 THEN 0,1
ELSEIF #Include = 0 THEN 0
END
So all you have to do is write an IN clause in the WHERE clause.
SELECT * FROM store
WHERE values IN (
SELECT ISNULL(CASE #Include WHEN 1 THEN 1 END,0)
UNION
SELECT ISNULL(CASE #Include WHEN 1 THEN 0 END,0)
)
I hope this helps anyone in the future!

How to Check IF condition in Case statement of Stored procedure

I am using CASE Statement in Stored procedure. I am using like
create proc USP_new
(
#searchtype varchar(30),
#stateName char(2),
#keywords varchar(300),
#locations varchar(100),
#searchBy varchar(20),
#keywordOption varchar(5),
#jobType char(4),
#startDate varchar(20),
#endDate varchar(20),
#companyID int
)
as begin
declare #mainQuery varchar(8000)
SELECT #mainQuery = 'SELECT JobID, JobTitle, CompanyInfo, JobSummaryLong, ModifiedDate
FROM Jobs
WHERE IsActive = 1 '
IF #startDate = '' BEGIN
SELECT #mainQuery = #mainQuery + 'And ModifiedDate >= ''' + #startDate + ' 00:00:00'' '
END
SELECT #mainQuery = #mainQuery + 'And ModifiedDate <= ''' + #endDate + ' 23:59:59'''
SELECT
CASE #mainQuery
WHEN 'state' THEN 'ONE'
WHEN 'keyword' THEN 'Second'
WHEN 'company' THEN 'Third'
ELSE 'Other'
END
I want check more condition on this 'Keyword' like When Keyword and keyword is not null then
goto THEN condition..
I used like WHEN 'keyword' AND (#keyword IS NULL) THEN '' but its is giving syntax error.
IT is possible to check condition like this or any other way to check this
Thanks....
It's really hard to tell what you are trying to accomplish with this stored proc, but I think you are definitely making thing harder than they need to be. You could probably re-write this as a single query like so:
SELECT
KeywordResult = CASE
WHEN #keywords = 'state' THEN 'ONE'
WHEN #keywords = 'keyword' THEN 'Second'
WHEN #keywords = 'company' THEN 'Third'
ELSE 'Other' END,
JobID,
JobTitle,
CompanyInfo,
JobSummaryLong,
ModifiedDate
FROM
Jobs
WHERE
IsActive = 1
AND (#StartDate <> '' AND ModifiedDate >= #StartDate)
AND ModifiedDate <= #endDate + ' 23:59:59'''