SQL query date null check - sql

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

Related

SQL Server stored procedure optional parameters, include all if null

I have this stored procedure:
ALTER PROCEDURE [dbo].[GetCalendarEvents]
(#StartDate datetime,
#EndDate datetime,
#Location varchar(250) = null)
AS
BEGIN
SELECT *
FROM Events
WHERE EventDate >= #StartDate
AND EventDate <= #EndDate
AND (Location IS NULL OR Location = #Location)
END
Now, I have the location parameter, what I want to do is if the parameter is not null then include the parameter in where clause. If the parameter is null I want to completely ignore that where parameter and only get the result by start and end date.
Because when I'm doing this for example:
EXEC GetCalendarEvents '02/02/2014', '10/10/2015', null
I'm not getting any results because there are other locations which are not null and since the location parameter is null, I want to get the results from all the locations.
Any idea how can I fix this?
ALTER PROCEDURE [dbo].[GetCalendarEvents]
( #StartDate DATETIME,
#EndDate DATETIME,
#Location VARCHAR(250) = NULL
)
AS
BEGIN
SELECT *
FROM events
WHERE EventDate >= #StartDate
AND EventDate <= #EndDate
AND Location = ISNULL(#Location, Location )
END
If a NULL column is a possibility, then this would work.
ALTER PROCEDURE [dbo].[GetCalendarEvents]
( #StartDate DATETIME,
#EndDate DATETIME,
#Location VARCHAR(250) = NULL
)
AS
BEGIN
IF ( #loc IS NULL )
BEGIN
SELECT *
FROM events
WHERE EventDate >= #StartDate
AND EventDate <= #EndDate
END
ELSE
BEGIN
SELECT *
FROM events
WHERE EventDate >= #StartDate
AND EventDate <= #EndDate
AND Location = #Location
END
END
As having an 'OR' clause should be reasonably avoided due to possible performance issues.
The part in the WHERE clause should then read
AND (#Location IS NULL OR Location=#Location)
Try this
SELECT *
FROM Events
WHERE EventDate >= #StartDate
AND EventDate <= #EndDate
AND Location = Case When LEN(#Location) > 0 Then #Location Else Location End
It can be easily done with a dynamic sql query.
ALTER PROCEDURE [dbo].[GetCalendarEvents]
(#StartDate datetime,
#EndDate datetime,
#Location varchar(250) = null)
AS
BEGIN
DECLARE #SQL NVARCHAR(MAX);
DECLARE #PARAMETER_DEFIINITION NVARCHAR(MAX);
DECLARE #WHERE_PART NVARCHAR(MAX);
SET #PARAMETER_DEFIINITION =' #StartDate DATETIME, #EndDate DATETIME, #Location VARCHAR(250) '
SET #SQL ='SELECT *
FROM Events
WHERE EventDate >= #StartDate
AND EventDate <= #EndDate '
IF #Location IS NOT NULL
BEGIN
SET #WHERE_PART = ' AND Location = #Location '
END
SET #SQL = #SQL + #WHERE_PART
EXEC SP_EXECUTESQL #SQL, #PARAMETER_DEFIINITION, #StartDate, #EndDate, #Location
END
Query will be dynamically created according to the parameters. In here if #location is null then it will not add to the where part.
If you want more on writing dynamic queries please refer this article. http://codingpulse.blogspot.com/2015/02/dynamic-sql-in-stored-procedure-part-1.html

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

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 )

Remove subquery from JOIN?

In the following query, I would like the remove the subquery from the JOIN statement (since my two SELECT statements are selecting data from same table). How can I use that alias? Thanks in advance for any help.
declare #StartDate datetime= '8/01/2011'
declare #EndDate datetime = '9/20/2011'
declare #PortfolioId int = 6
SELECT
Previous.PreviousNAV,
Todays.TodaysNAV,
ISNULL((Todays.TodaysNAV-Previous.PreviousNAV),0) NetChange,
ISNULL((Todays.TodaysNAV-Previous.PreviousNAV) / Todays.TodaysNAV,0) BAMLIndex
FROM
(
SELECT PortfolioId,ISNULL(NAV,0) PreviousNAV
FROM Fireball..NAV
WHERE Date BETWEEN #StartDate AND #EndDate and PortfolioId = #PortfolioId
) Previous
JOIN
(
SELECT PortfolioId,ISNULL(NAV,0) TodaysNAV
FROM Fireball..NAV
WHERE Date = #EndDate and PortfolioId = #PortfolioId
) Todays
ON Previous.PortfolioId = Todays.PortfolioId
Just eliminate the subqueries entirely. I don't think they add anything to the query. Try this instead:
SELECT
Previous.NAV as PreviousNAV,
Todays.NAV as TodaysNav,
ISNULL((Todays.NAV-Previous.NAV),0) NetChange,
ISNULL((Todays.NAV-Previous.NAV) / Todays.NAV,0) BAMLIndex
FROM
Fireball..NAV as Previous
JOIN
Fireball..NAV as Todays
ON Previous.portfolioID = Todays.PortfolioID
WHERE Previous.Date BETWEEN #StartDate AND #EndDate
AND Previous.PortfolioId = #PortfolioId
AND Todays.Date = #EndDate

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