Reputation: 3494
I am creating a stored procedure for searching. DateOrdered
is column name in table of datetime
type.
The problem is that I want to perform search on this column. The user can search on start date and end date. Also user can send null for any parameter, like start date or end date.
When the user will not send the start date or end date, I shall search on another option. My problem is that how can I handle this below is the query I tried, but without success
SELECT
@C_Order_ID = C_Order_ID
FROM
C_Order COrder
WHERE
(@AD_Org_ID IS NULL OR
COrder.AD_Org_ID IN (SELECT ID FROM fnSplitter(@AD_Org_ID)))
AND (@AD_Client_ID IS NULL OR
@AD_Client_ID IN (SELECT ID FROM fnSplitter(@AD_Client_ID)))
AND (@IsActive IS NULL OR COrder.IsActive = @IsActive)
AND (@startDate IS NULL OR
COrder.DateOrdered = @startDate BETWEEN @EndDate IS NULL
OR COrder.DateOrdered = @EndDate)
Thanks for your reply .
Upvotes: 1
Views: 95
Reputation: 172378
You may try like this:
COrder.DateOrdered BETWEEN @startDate AND @EndDate
So your query would be like
SELECT @C_Order_ID= C_Order_ID FROM C_Order COrder
WHERE
(@AD_Org_ID IS NULL OR COrder.AD_Org_ID IN (Select ID From fnSplitter(@AD_Org_ID)))
AND (@AD_Client_ID IS NULL OR @AD_Client_ID IN (Select ID From fnSplitter(@AD_Client_ID)))
AND (@IsActive IS NULL OR COrder.IsActive = @IsActive)
AND (@startDate IS NULL OR COrder.DateOrdered BETWEEN isnull(@startDate,'') AND isnull(@EndDate,''))
or better
SELECT @C_Order_ID= C_Order_ID FROM C_Order COrder
WHERE
(@AD_Org_ID IS NULL OR COrder.AD_Org_ID IN (Select ID From fnSplitter(@AD_Org_ID)))
AND (@AD_Client_ID IS NULL OR @AD_Client_ID IN (Select ID From fnSplitter(@AD_Client_ID)))
AND (@IsActive IS NULL OR COrder.IsActive = @IsActive)
AND (CAST(@startDate AS DATE) IS NULL OR (CAST(@startDate AS DATE) IS NULL OR CAST(COrder.DateOrdered AS DATE) >=CAST(@startDate AS DATE))
AND (CAST(@endDate AS DATE) IS NULL OR CAST(COrder.DateOrdered AS DATE) <=CAST(@endDate AS DATE))
Upvotes: 1
Reputation: 69749
Aaron Bertrand has written a good article about using BETWEEN with date ranges - What do BETWEEN and the devil have in common?, this is worth a read. Also it looks like you are passing a comma separated list in a string, then splitting it with a function fnsplitter
, you may want to consider using table-valued paramters
However, to actually answer your question you can use the above idea of not using between and change your query to:
AND (@startDate IS NULL OR COrder.DateOrdered >= @startDate)
AND (@EndDate IS NULL OR COrder.DateOrdered <= @EndDate)
So you have 4 permutations.
Based on your comments on another answer, it sounds like you may be passing a date as the @EndDate parameter, e.g. 2014-08-28
, but still want to include all records on that date, even if they have a time associated, e.g. 2014-08-28 12:00
, this is exactly why BETWEEN is not used for date ranges, instead you need to use the less than operator and add 1 day to your End date:
AND (@startDate IS NULL OR COrder.DateOrdered >= @startDate)
AND (@EndDate IS NULL OR COrder.DateOrdered < DATEADD(DAY, 1, @EndDate))
Upvotes: 0
Reputation: 709
SELECT @C_Order_ID= C_Order_ID FROM C_Order COrder
WHERE
(@AD_Org_ID IS NULL OR COrder.AD_Org_ID IN (Select ID From fnSplitter(@AD_Org_ID)))
AND (@AD_Client_ID IS NULL OR @AD_Client_ID IN (Select ID From fnSplitter(@AD_Client_ID)))
AND (@IsActive IS NULL OR COrder.IsActive = @IsActive)
AND (@startDate IS NULL OR COrder.DateOrdered BETWEEN @startDate AND @EndDate
OR COrder.DateOrdered = @EndDate)
Upvotes: 0