condition in where clause with optional parameter - sql

There are thee input parameter in my stored procedure. for example,
DECLARE #fromDate DateTime = NULL
DECLARE #toDate DateTime = NULL
DECLARE #Id int = NULL
I want to write a condition in where clause like...if fromDate is provided then searching must be done on #fromDate. if #fromDate is not provided then check for #Id variable if this is not null then search basis on #Id...
Something like...
where
CASE
when #fromDate is not null
THEN (#FromDate is null or ([Created] between #FromDate and #ToDate))
ELSE (#requestId is null or Id=#requestId)
there is one problem with below solution...if #fromDate and #Id both are provided then this will do intesect of them and nothing is return.....condition should be like...if #fromDate is given the priority gives to #fromDate even if #Id is provided and result must not be dependend to #Id parameter....

Because you depend on both parameters you than can use them both in condition:
where
(#FromDate is null or ([Created] between #FromDate and #ToDate))
or
((#requestId is null or Id=#requestId)
and #FromDate is null) ----mix #requestId & #FromDate

Do you mean this? Please check:
WHERE [Created] BETWEEN
(CASE WHEN #FromDate IS NOT NULL THEN #FromDate ELSE [Created] END) AND
(CASE WHEN #ToDate IS NOT NULL THEN #ToDate ELSE [Created] END) AND
Id=(CASE WHEN #requestId IS NOT NULL THEN #requestId ELSE Id END)

Related

Stored procedure returns no records when datetime filters are NULL?

Consider this stored procedure :
CREATE PROCEDURE [dbo].[sp_getclients]
#FromDate datetime, #ToDate datetime
AS
BEGIN
SET NOCOUNT ON;
SELECT *
FROM CM.Clients
--If both dates are not NULL then also check PurchaseDate to be between them
WHERE
(#FromDate IS NOT NULL AND #ToDate IS NOT NULL
AND Clients.PurchaseDate >= #FromDate
AND Clients.PurchaseDate <= #ToDate)
OR
--If #FromDate is not NULL AND #ToDate IS NULL then also check PurchaseDate to be greater than #FromDate
(#FromDate IS NOT NULL AND #ToDate IS NULL
AND Clients.PurchaseDate >= #FromDate)
OR
--If #FromDate is NULL AND #ToDate IS NOT NULL then also check Trans_Date to be less than #ToDate
(#FromDate IS NULL AND #ToDate IS NOT NULL
AND Clients.PurchaseDate <= #ToDate)
END
When I execute this stored procedure with NULL parameters, no records are returned.
Any idea where I did go wrong here?
Add this:
OR
(#FromDate IS NULL AND #ToDate IS NULL)

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)))

Determine if two parameters are null, then use parameters in the where clause

Good day, I receive 2 nullable date parameters in my stored procedure. #StartDate and #EndDate. I need to execute my procedure as normal if these two parameters are NULL, else the #StartDate param needs to be >= my StartDateTime value AND #EndDate param needs to be <= my EndDateTime value.
Below is a snippet of what I am trying to accomplish but are not sure of the syntax.
FROM DI_Intervention_Schedule S
WHERE
(
#ID IS NULL
OR S.[ID] = #ID
)
AND (
CASE #StartDate WHEN IS NOT NULL THEN
#StartDate >= S.[StartDateTime] AND #EndDate <= S.[EndDateTime]
END
)
Any help please?
Try below code :
FROM DI_Intervention_Schedule S
WHERE
(S.[ID] = #ID OR #ID IS NULL)
AND (( S.[StartDateTime] >= #StartDate AND S.[EndDateTime] <= #EndDate) OR #StartDate IS NULL )

T-SQL - Using CASE with Parameters in WHERE clause

I'm running a report on a Sales table:
SaleId INT | SalesUserID INT | SiteID INT | BrandId INT| SaleDate DATETIME
I'm having a nightmare trying to do something like this with a set of Nullable parameters #SalesUserID, #SiteId, #BrandID and two DateTime params.
Additional Point: Only ONE of the filter parameters will ever be passed as a Non-Null value.
SELECT * from Sales
WHERE
SaleDate BETWEEN #StartDate AND #EndDate
AND
SalesUserID IN
(
Select SalesUserID FROM Sales
WHERE
SaleDate BETWEEN #StartDate AND #EndDate
AND
CASE
WHEN #SalesUserId IS NOT NULL THEN SalesUserId = #SalesUserID
WHEN #SiteId Is Not Null THEN SiteId = #SiteId
ELSE BrandId = #BrandID
END
)
My use of CASE here smells bad but I'm not sure how to correct it. Can you please assist?
Thanks.
5arx
I don't think you want a CASE statement at all, but a compound conditional... Give this a shot and let me know:
select *
from Sales
where SaleDate between #StartDate and #EndDate
and
(
(#SalesUserId is not null and SalesUserId = #SalesUserID)
or (#SiteId is not null and SiteId = #SiteId)
or (BrandId = #BrandID)
)
If I understood you correctly, you want the three conditions either be NULL or checked for:
WHERE
/* ... */
AND SalesUserId = ISNULL(#SalesUserId, SalesUserId)
AND SiteId = ISNULL(#SiteId, SiteId)
AND BrandId = ISNULL(#BrandID, BrandID)
Be aware that this forces a table scan which might not be in your best interest.
This should work and use any index if you want to use CASE:
SELECT *
from Sales
WHERE SaleDate BETWEEN #StartDate AND #EndDate
AND SalesUserID = CASE WHEN #SalesUserID IS NULL THEN
SalesUserID ELSE #SalesUserID END
COALESCE() returns the 1st non NULL argument so you could;
...
WHERE SaleDate BETWEEN #StartDate AND #EndDate
AND SalesUserId = COALESCE(#SalesUserId, SalesUserId)
AND SiteId = COALESCE(#SiteId, SiteId)
AND BrandID = COALESCE(#BrandID, BrandId)
I would use a dynamic generated code in such a circumstance:
declare #SalesUserId int,#SiteId int,#StartDate datetime, #EndDate datetime,#BrandID int
declare #sql nvarchar(max)
set #sql = N'
SELECT * from Sales
WHERE
SaleDate BETWEEN #StartDate AND #EndDate
AND
SalesUserID IN
(
Select SalesUserID FROM Sales
WHERE
SaleDate BETWEEN #StartDate AND #EndDate AND
' +
CASE
WHEN #SalesUserId IS NOT NULL THEN 'SalesUserId = #SalesUserID'
WHEN #SiteId Is Not Null THEN 'SiteId = #SiteId'
ELSE 'BrandId = #BrandID'
END
+')'
print #sql
exec sp_executesql #sql
, N'#SalesUserId int,
#SiteId int,
#StartDate datetime,
#EndDate datetime,
#BrandID int'
,#SalesUserId
,#SiteId
,#StartDate
,#EndDate
,#BrandID
This is generally a job for dynamic SQl if you want performance.
http://www.sommarskog.se/dynamic_sql.html
Try this:
SELECT *
from Sales
WHERE SaleDate BETWEEN #StartDate AND #EndDate
AND SalesUserID = CASE WHEN #SalesUserID IS NULL THEN
SalesUserID ELSE #SalesUserID END

SQL query date null check

I have the following stored procedure.
ALTER PROCEDURE [dbo].[spList_Report]
#id INT,
#startDate DATETIME = NULL,
#endDate DATETIME = NULL,
#includeStatus1 BIT,
#includeStatus2 BIT,
#includeStatus3 BIT,
#includeStatus4 BIT
AS
SET NOCOUNT ON
SELECT *
FROM
tblProducts as products
WHERE
product.intID = #id
AND product.dateMain >= #startDate
AND product.dateMain <= #endDate
If #startDate AND #endDate are both null then I want it to return the rows ignoring the date check in the where clause.
How?
This should do
AND product.dateMain >= ISNULL( #startDate, 0)
AND product.dateMain <= ISNULL( #endDate, product.dateMain + 1)
ISNULL yields the second value, if the first value is null.
Thus:
if #startDate is null, then dateMain must be bigger than 0 (1900-01-01)
if #endDate is null, then dateMain must be smaller than dateMain + 1 day
you can try something like this
ALTER PROCEDURE [dbo].[spList_Report]
#id INT,
#startDate DATETIME = NULL,
#endDate DATETIME = NULL,
#includeStatus1 BIT,
#includeStatus2 BIT,
#includeStatus3 BIT,
#includeStatus4 BIT
AS
SET NOCOUNT ON
SELECT *
FROM
tblProducts as products
WHERE
product.intID = #id
AND product.dateMain >= ISNULL( #startDate, product.dateMain )
AND product.dateMain <= ISNULL( #endDate, product.dateMain )
You can utilize an "or" in your Sql, but since this is a stored procedure:
If #startdate is null Or #enddate is null
begin
select without using a date range
end
Else
begin
select using date range
end
I would use Kris Krause's solution, but change the "IF" statement to use "AND". I think if you use the first two solutions the query engine may perform a table/index scan on the date fields. You want to keep your queries as concise as possible for best performance, so don’t run queries on unnecessary columns.
IF #startdate IS NULL AND #enddate IS NULL
BEGIN
SELECT * FROM tblProducts as products WHERE
product.intID = #id
END
ELSE
BEGIN
SELECT * FROM tblProducts as products WHERE
product.intID = #id
AND product.dateMain >= #startDate
AND product.dateMain <= #endDate
END