How can I include null values in BETWEEN clause? - sql

In my query's where clause I have the condition:
User.DateOfBirth BETWEEN #startDate AND #endDate
Where #startDate and #endDate are nullable. If #startDate is null, I want all values less than or equal to #endDate; if #endDate is null, I want all values greater than or equal to #startDate; if both are null I want all values.
My failed attempt - returns 0 results
((( User.DateOfBirth > #startDate) OR (#startDate Is null)) AND (( User.DateOfBirth < #endDate) OR (#endDate is null)) )
(Editor's note: BETWEEN includes the end points (less/greater than or equal), but the description for the null cases didn't. I've assumed this is an oversight.

Try this:
[User].DateOfBirth BETWEEN ISNULL(#startDate,[User].DateOfBirth) AND ISNULL(#endDate,[User].DateOfBirth)

Two approaches spring to mind:
Tread the four cases separately and then OR them together:
start and end are null: any date matches,
start is null, so need DoB <= end
send is null, so need DoB >= start
neither is null, so need between
This will lead to a long expression.
Use IsNull:
As shown by mehdi lotfi in his answer.

If you are using a nullable datetime type you could use
User.DateOfBirth BETWEEN isnull(#startDAte, CAST('1753-01-01' AS datetime)) AND isnull(#endDAte, CAST('9999-12-31' AS datetime))
for datetime2 use
User.DateOfBirth BETWEEN isnull(#startDAte, CAST('0001-01-01' AS datetime2)) AND isnull(#endDAte, CAST('9999-12-31' AS datetime2))

WHERE
((User.DateOfBirth BETWEEN #startDAte AND #endDAte) AND #startDAte is not null AND #endDAte is not null)
OR
((User.DateOfBirth =< #endDAte) AND #startDAte is null AND #endDAte is not null)
OR
((User.DateOfBirth >= #startDAte) AND #startDAte is not null AND #endDAte is null)
OR
(1=1 AND #startDAte is null AND #endDAte is null)

Try this:
select * from yourtable
where
(#startdate is null and #enddate is null)
or
(#startdate is null and #enddate is not null and User.DateOfBirth <= #enddate)
or
(#startdate is not null and #enddate is null and User.DateOfBirth >= #startdate)
or
(#startdate is not null and #enddate is not null and User.DateOfBirth BETWEEN #startdate AND #enddate)
This addresses all possible cases:
Both parameters are null - return all results
Non null end date only - return all results where DOB <= end date
Non null start date only - return all results where DOB >= start date
Both parameters are non null - return all results where DOB is between start and end dates

Related

Using a CASE or IF..ELSE within WHERE clause's AND part - SQL Server

I have a stored procedure in SQL Server.
The SELECT part for this SP is as follows :
SELECT * FROM demoTable dt
INNER JOIN demoTable2 dt2
WHERE
(#StartDate IS NULL OR dt.StartDate = #StartDate OR (dt.StartDate >= #StartDate and dt.EndDate <= #EndDate))
AND (#EndDate IS NULL OR dt.EndDate = #EndDate OR (dt.StartDate >= #StartDate and dt.EndDate <= #EndDate))
Now I want to modify the above WHERE clause part after the AND condition.
I have added 3 new parameters/variables which are being passed to this SP.
#ID int , #isAdmin int and #Date varchar(50)
Using the values of these variables I'm trying to manipulate the above WHERE clause as follows :
WHERE
#StartDate IS NULL OR dt.StartDate = #StartDate OR (dt.StartDate >= #StartDate and dt.EndDate <= #EndDate))
-- Logic change below
AND(
CASE WHEN (#ID != 100 AND #isAdmin != 1)
THEN (#EndDate IS NULL OR dt.EndDate = #EndDate OR (dt.StartDate >= #StartDate and dt.EndDate <= #EndDate))
ELSE (dt.EndDate>sysdatetime())
END)
But after this modification I'm receiving an error.
Error statement :
Incorrect syntax near the keyword 'IS'.
This error is pointing to the line where I've used IS NULL from the modified logic part.
Basically what I want to do is to apply the original logic for AND i.e.
(#EndDate IS NULL OR dt.EndDate = #EndDate OR (dt.StartDate >= #StartDate and dt.EndDate <= #EndDate))
only when the
(#ID != 100 AND isAdmin != 1)
holds true or else I want to apply the new logic i.e.
(dt.EndDate>sysdatetime()
How can I achieve this?
If you want a special condition for #ID !=100 AND isAdmin !=1
You don't need case/when, you need just a valid boolean expression
change :
AND(
CASE WHEN (#ID != 100 AND isAdmin != 1)
THEN (#EndDate IS NULL OR dt.EndDate = #EndDate OR (dt.StartDate >=
#StartDate and dt.EndDate <= #EndDate))
ELSE (dt.EndDate>sysdatetime())
END
)
to
AND(
((#ID != 100 AND isAdmin != 1) AND (#EndDate IS NULL OR dt.EndDate = #EndDate OR (dt.StartDate >= #StartDate and dt.EndDate <= #EndDate)))
OR
((#ID == 100 OR isAdmin == 1) AND (dt.EndDate>sysdatetime()) )
)

how to deal withenddate null value when you do DATEADD(dd,1, s.endDate))

I have startDate and endDate but I find problem some endDate has null value when I do get value between startDate and endDate +1 I get 0 value because of endDate is null
Select* form s where AND (GETDATE() >= s.startDate AND GETDATE() <= DATEADD(dd,1, s.endDate))
the DATEADD will return null because endDate is null.just I want to ask when I search for range hoe cvan I deal the endDate has null value ?
Try this
Select* form s where AND (GETDATE() >= s.startDate AND
GETDATE() <= DATEADD(dd,1, COALESCE(s.endDate,s.startDate))
DECLARE #nowStart DATETIME = GETDATE();
DECLARE #nowEnd DATETIME = DATEADD(dd, -1, #nowStart)
Select *
from s
where (#nowStart >= s.startDate
and (s.endDate is null or #nowEnd <= s.endDate))

Select query result should return based on passing parameters in procedures without using if else statement?

select
id,
starttime,
endtime,
name
from
table1
where
id != 0
and starttime >= #startdate and endtime <= #enddate
In the above query, how do I perform if the #startdate and #enddate parameter is null by without using if else?
starttime >= #startdate and endtime <= #enddate this condition should check if #startdate and #enddate is not null. else it won't to check.
Any suggestion for this?
you simply check that the variable is null thus returning true as as appropriate
doing this individually for each parameter
where (startdate >= #startdate or #startdate is null)
and (enddate <= #enddate or #enddate is null)
you could also 'ignore' the criteria if either are null
where ((startdate >= #startdate and enddate <= #enddate)
or #startdate is null
or #enddate is null)
All you need is ISNULL or COALESCE function in the where condition.
select id,
starttime,
endtime,
name
from table1
where
id != 0 and
starttime >= ISNULL(#startdate,starttime) and endtime <= ISNULL(#enddate,endtime)
Add extra condition:
and #startdate is not null and #enddate is not null
try this:
for this
should check if #startdate and #enddate is not null. else it won't to check use first answer
if #startdate is null then it will return true and gives all result
select id,
starttime,
endtime,
name
from table1
where
id != 0 and
(starttime >= #startdate or #startdate is null )
and
(endtime <= #enddate or #enddate is null)
or
select id,
starttime,
endtime,
name
from table1
where
id != 0 and
(starttime >= #startdate and #startdate is NOT null )
and
(endtime <= #enddate and #enddate is NOT null)
Try to use OR to check this:
where
(id != 0)
and
(
(#startdate IS NULL) OR (#enddate IS NULL)
OR
(starttime >= #startdate and endtime <= #enddate)
)

Return date which I get as parameter in Stored Procedure

This is my stored procedure which I am connecting with crystal report and I want to return start date and end date which is I am getting from parameters like if date is null then nothing shows on reports but if date has some value then that value prints.
CREATE PROCEDURE [dbo].PatientClaimInfo
#StartDate Date = NULL,
#EndDate Date = NULL
AS
BEGIN
select p.VLNAME + ' ' + p.VFNAME AS Patients_Name, p.IPATID AS Patient_ID, p.DDOB AS dob,
d.NCOPAY, d.NVTOTPLAN, d.NVWOPLAN, d.NVWOPAT, d.NVADJPLAN, d.NVADJPAT, d.NVPAIDPLAN,
d.NVPAIDPAT, d.NVBALPLAN, d.NVBALPAT, d.NAPPTBAL, d.VPAYSTAT AS Status
From pmvixtr d
INNER JOIN pmptxft p ON p.IPATID = d.IPATID
Where #StartDate <= d.DSDATE AND #EndDate >= d.DSDATE
END
In your select statement you can include #StartDate, #EndDate
e.g.
select #StartDate, #EndDate, .... <rest of your select statement>...
I would also suggest in your where clause use Where d.DSDATE BETWEEN(#StartDate, #EndDate)
If you don't want to select anything if #StartDate and #EndDate is NULL, having that in WHERE Clause can be very expensive... I suggest have an if condition
IF #StartDate IS NOT NULL AND #EndDate IS NOT NULL
select.....
END IF
Try
CREATE PROCEDURE [dbo].PatientClaimInfo
#StartDate Date = NULL,
#EndDate Date = NULL
AS
BEGIN
IF (#StartDate Date IS NOT NULL AND #EndDate Date IS NOT NULL)
THEN
select p.VLNAME + ' ' + p.VFNAME AS Patients_Name, p.IPATID AS Patient_ID, p.DDOB AS dob,
d.NCOPAY, d.NVTOTPLAN, d.NVWOPLAN, d.NVWOPAT, d.NVADJPLAN, d.NVADJPAT, d.NVPAIDPLAN,
d.NVPAIDPAT, d.NVBALPLAN, d.NVBALPAT, d.NAPPTBAL, d.VPAYSTAT AS Status
From pmvixtr d
INNER JOIN pmptxft p ON p.IPATID = d.IPATID
Where #StartDate <= d.DSDATE AND #EndDate >= d.DSDATE
END
END

SQL Server Optional Parameter Date from to

I have a stored procedure and I want to search between the from and to date, but:
if #FromDate is not null and #ToDate is not null then
vSaleDetail.date between #FromDate and #ToDate
if #FromDate is not null and #ToDate is null then
vSaleDetail.date = #FromDate
if #FromDate is null and #ToDate is then
Return All
This is what I have but it is not working
where
(((#FromDate is null and #ToDate is null) OR (vSaleDetail.date between #FromDate and #ToDate ))
AND ((#FromDate is null) OR (vSaleDetail.date = #FromDate)))
Please help — what do I need to do to fix it?
I would poulate the null parameters with dates way outside the range you need. So If form date is null, I would populate with the earlies t accepatable date in your database's datetime data type. The To date would be poulated with the latest possible date. Then you don't need to use all that complex logic which slows things down.
IF #FromDate is null
Begin
Set #Fromdate = '17530101'
END
IF #ToDATE is null
BEGIN
SET #Todate = '99991231'
END
select ...
WHERE vSaleDetail.date >=#FromDate and <= #ToDate
You can try this:
WHERE (vSaleDetail.date BETWEEN #FromDate AND ISNULL(#ToDate,#FromDate)
OR COALESCE(#FromDate, #ToDate) IS NULL)
ISNULL(p1, p2):
if p1 IS NULL then p2 is returned, otherwise p1 is returned
COALESCE(p1, p2, ...):
Like ISNULL(). returns p1 unless it is NULL, in which case, p2 is returned unless it is NULL, in which case p3.... if all parameters in COALESCE() are null, NULL is returned.
Try this:
WHERE
(
( #FromDate IS NULL AND #ToDate IS NULL)
OR
( vSaleDetail.date BETWEEN #FromDate AND #ToDate )
)
OR <-- #FromDate IS NULL AND #FromDate IS NULL
( #FromDate IS NULL OR vSaleDetail.date = #FromDate )
declare #default_min_date datetime;
declare #default_max_date datetime;
SET #default_min_date = 0
SET #default_max_date = 2958463;
SELECT *
FROM MyTable
WHERE
myDateColumn >= Isnull(#DateFrom, #default_min_date) AND myDateColumn <= Isnull(#DateTo, #default_max_date)
AND (#DateFrom IS NULL OR CONVERT(DATETIME, [CreationDate], 103) BETWEEN CONVERT(DATETIME, #DateFrom, 103) AND DATEADD(DAY, 1, CONVERT(DATETIME, ISNULL(#DateTo, #DateFrom), 103)))