I have a start date and end date column in my table and I get a start date and end date as input. I need to set START date as TBL.StartDate if it is after INPUT Start Date and I need to set END date as TBL.EndDate if it is before INPUT End Date. Finally count the days between START and END.
I'm trying to use if statement but I fail when I try to use if in select query.
I'm not sure if this is a correct way of solving this problem.
Declare #Start Date;
Declare #End Date;
Declare #INPUT_StartDate Date;
Declare #INPUT_EndDate Date;
set #INPUT_StartDate = '2019-01-01'; --user input
set #INPUT_EndDate = '2019-04-20'; --user input
select
TBL.StartDate,
TBL.EndDate,
#INPUT_StartDate,
#INPUT_EndDate,
if(TBL.StartDate < INPUT_StartDate) set #Start = TBL.STARTDate;
else set #Start = INPUT_StartDate;
if(TBL.EndDate < INPUT_EndDate) set #End = INPUT_EndDate;
else set #End = TBL.EndDate;
#DateDiff(day, #Start, #End) as COUNT
from TBL
I'm expecting that this comparison happens, but i guess i'm using if statement in between select query is not allowed?
Actual results are quite a few syntax errors near if.
You can make sure of case statement which is same as if but used in case statement. if you want to use if in select list(there is IIF if your sql server is 2012+). If is mostly used in conditional logic.
I removed #start and #end date variable which might not be required based on the logic you are using.
select '2019-03-20' as startdate, '2019-04-20' as ENddate into #temp union all
select '2018-02-01' as startdate, '2019-03-20' as ENddate
Declare #Start Date;
Declare #End Date;
Declare #INPUT_StartDate Date;
Declare #INPUT_EndDate Date;
set #INPUT_StartDate = '2019-01-01'; --user input
set #INPUT_EndDate = '2019-04-20'; --user input
select
TBL.StartDate,
TBL.EndDate,
#INPUT_StartDate INPUT_StartDate,
#INPUT_EndDate INPUT_EndDate,
datediff(day, case when tbl.StartDate < #INPUT_StartDate then TBL.STARTDate
else #INPUT_StartDate end,
case when TBL.EndDate < #INPUT_EndDate then #INPUT_EndDate
else TBL.EndDate end) date_diff
from #temp tbl
Output:
Startdate Enddate Input_startdate input_enddate date_diff
2019-03-20 2019-04-20 2019-01-01 2019-04-20 109
2018-02-01 2019-03-20 2019-01-01 2019-04-20 443
SQL Server doesn't have least() or greatest(). And SQL Server doesn't allow you to mix selecting columns with setting variables.
I recommend setting the values in a "subquery", in this case, using apply:
select t.StartDate, t.EndDate,
#INPUT_StartDate, #INPUT_EndDate,
DateDiff(day, v.dateStart, v.dateEnd) as num_days
from tbl t cross apply
(values (case when t.StartDate < #INPUT_StartDate
then t.STARTDate
else #INPUT_StartDate
end,
case when t.EndDate < #INPUT_EndDate
then INPUT_EndDate
else #TBL.EndDate
end
)
) v(startDate, endDate);
declare #StartDate datetime,#msg varchar(100),#Diff int
declare #EndDate datetime
declare #TodayDate datetime
set #StartDate = '2019-04-23' ---Define Start Date-----
set #EndDate = '2019-04-30' ---Define End Date-----
set #TodayDate = GETDATE()
if(#StartDate < #TodayDate)
begin
set #msg = 'Date is Smaller than today date'
select #msg
end
else
begin
select #Diff = DATEDIFF(day,#StartDate,#EndDate)
set #msg = #Diff
select #msg as Days_Differance
end
Related
Using string parameter for start date and end date. Passing this values to a sql task editor in SSIS. Wanted to convert the start date to day - 1 and end date to + 1 day and then process the variable. My actual code is as below:
DECLARE #P_StartDate VARCHAR(100)
DECLARE #P_EndDate VARCHAR(100)
SET #P_StartDate = ?
SET #P_EndDate = ?
IF (#P_StartDate!='' AND #P_EndDate!='')
BEGIN
SELECT #P_StartDate , #P_EndDate
END
Wanted to do the changes like below but this is not working. Please help.
DECLARE #P_StartDate VARCHAR(100)
DECLARE #P_EndDate VARCHAR(100)
SET #P_StartDate = ?
SET #P_EndDate = ?
#P_StartDate = DATEADD(day, -1, convert(date, max(#P_StartDate), 102)
#P_EndDate = DATEADD(day, 1, convert(date, max(#P_EndDate), 102)
IF (#P_StartDate!='' AND #P_EndDate!='')
BEGIN
SELECT #P_StartDate , #P_EndDate
END
Edit: I cannot use the variable as date type because i am using this string type variable to dynamically generate one big sql query inside another ssis variable. Can anyone please guide me if it is possible to achieve the same thing without using datetype variable.
Your script is ok, there is syntax error,
DECLARE #P_StartDate VARCHAR(100)
DECLARE #P_EndDate VARCHAR(100)
SET #P_StartDate = '2021-10-20'
SET #P_EndDate = '2021-10-30'
set #P_StartDate = DATEADD(day, -1, convert(date, #P_StartDate, 102))
set #P_EndDate = DATEADD(day, 1, convert(date, #P_EndDate, 102))
IF (#P_StartDate!='' AND #P_EndDate!='')
BEGIN
SELECT #P_StartDate , #P_EndDate
END
notice extra ")" here DATEADD(day, -1, convert(date, #P_StartDate, 102))
Why use max ?
Really this is not clear,what you are trying to do.
Edit: I cannot use the variable as date type because i am using this
string type variable to dynamically generate one big sql query inside
another ssis variable
I'm not sure if I get this right. Please someone explain to me. I don't know what deatiles should I add to shis function. I gues somwone who knows sql well will know this easily
declare #date datetime = '2016-05-01',
#ndays INT = 11,
#country NVARCHAR(2)
BEGIN
IF #date IS NULL
BEGIN
SET #date = GETDATE();
END
IF #country IS NULL
BEGIN
SET #country = 'HU';
END
DECLARE #count INT = 1
DECLARE #newdate datetime
DECLARE #firstdayofmonth date = DATEADD(month, DATEDIFF(month, 0, #date), 0)
WHILE DATEPART(weekday,#firstdayofmonth) in (7,1)
BEGIN
SET #firstdayofmonth = DATEADD(DAY, 1, #firstdayofmonth)
END;
SET #newdate = #firstdayofmonth
WHILE #count < #ndays
BEGIN
SET #newdate = DATEADD(DAY, 1, #newdate)
IF (DATEPART(WEEKDAY, #newdate) not in (1,7))
SET #count += 1;
END
select #newdate
END
I get that this is about declaring a date. The firstdayofmonth calculatio is confusing in it.
This is clearly no mysql code weekday goes from 0 to 6. Also you can't declare variables that way.
Also you should have posted the whole code.
AS for your code:
The first While Clause searches for the first Monday in a Month.
The second counts all Working Days (Monday till Friday) of that chosen Month.
With the first variables, you can manipulate which Month, but what that country has to do with it I can only guess that you have a list of all public holiday fur Hungary.
#newdate becomes the first weekday of the month (Monday-Friday). If the month starts on a weekend (Saturday or Sunday), it shifts up until Monday; otherwise it stays the same. As for the second part, #count looks like it ends up being the number of weekdays in the first eleven days since the start of the first weekday.
I have the following query:
DECLARE #Month int
DECLARE #Year int
set #Month = 2
set #Year = 2004
Declare #MonthStartDate datetime
declare #MonthEndDate datetime
set #MonthStartDate = 'select DATEADD(month,#Month-1,DATEADD(year,#Year-1900,0))'
set #MonthEndDate = 'select DATEADD(day,-1,DATEADD(month,#Month,DATEADD(year,#Year-1900,0)))'
return #MonthStartDate , #MonthEndDate
But it returns:
"Conversion failed when converting date and/or time from character string."
What's wrong here?
Alternatively, you can also use as follow..
select #MonthStartDate = DATEADD(month,#Month-1,DATEADD(year,#Year-1900,0))
select #MonthEndDate = DATEADD(day,-1,DATEADD(month,#Month,DATEADD(year,#Year-1900,0)))
You should use DateTime expression instead of string literal. Just remove quotes:
DECLARE #Month int
DECLARE #Year int
set #Month = 2
set #Year = 2004
Declare #MonthStartDate datetime
declare #MonthEndDate datetime
set #MonthStartDate = DATEADD(month,#Month-1,DATEADD(year,#Year-1900,0))
set #MonthEndDate = DATEADD(day,-1,DATEADD(month,#Month,DATEADD(year,#Year-1900,0)))
Looking at your Query (Since you don't have enough Description on the Question ) What I understood is that you are trying to get the First and Last day of a Given month. If you are using a SQL Server Version 2012 or Above, then you have an Inbuild Function called EOMONTH() which can be used to calculate the End of any given month. Otherwise, you may try the below method on any Version on SQL Server
Declare #MonthStartDate datetime,
#MonthEndDate datetime,
#Year int,
#Month int --It's Better to Declare all the variables in the same space for easy handling
SELECT
#Month = 2,
#Year = 2004 -- Common Assignments can be done together
;WITH MNT
AS
(
SELECT
MonthStartDate = CAST(#Month AS VARCHAR(20))+'/01/'+CAST(#Year AS VARCHAR(20)) -- Hardcoded Day as 1 since Month Start always at 1
)
SELECT
#MonthStartDate = MonthStartDate,
#MonthEndDate = DATEADD(DAY,-1,DATEADD(MONTH,1,MonthStartDate))
FROM MNT
I have an SSIS for loop and in the assign expression part of the for loop I need to increment with a DATEADD function but the date part needs to be dependent on my variable:
#DateStart = DATEADD(#TypeIncrement,#DayIncrement,#DateStart)
If i change it ,it will work:
#DateStart = DATEADD(dd,#Increment,#DateStart)
but if I try to do it this way its just giving me an error saying The date part parameter specified for function "DATEADD" is not valid.
I have also tried changing it to be a case statement with different date parts but that wouldn't work either.
Any ideas?
Thanks.
----------------EDIT
a lot of ppl are posting sql server answers. but i need it working here:
Example
Declare #TypeIncrement varchar(10) = 'MM'
Declare #DayIncrement int = 5
Declare #DateStart date = '2017-03-15'
Select Case #TypeIncrement
When 'YY' then DateAdd(YY, #DayIncrement, #DateStart)
When 'QQ' then DateAdd(QQ, #DayIncrement, #DateStart)
When 'MM' then DateAdd(MM, #DayIncrement, #DateStart)
When 'WK' then DateAdd(WK, #DayIncrement, #DateStart)
When 'DD' then DateAdd(DD, #DayIncrement, #DateStart)
End
Returns
2017-08-15
The first parameter doesn't accept a variable as an input. One alternate option to a CASE might be dynamic SQL:
DECLARE #IncrementType nvarchar(10), #Increment int, #DateStart date;
SET #IncrementType = N'DAY';
SET #Increment = 5;
SET #DateStart = GETDATE();
IF #IncrementType NOT IN (N'YEAR',N'QUARTER',N'MONTH',N'DAYOFYEAR',N'DAY',N'WEEK',N'WEEKDAY',N'HOUR',N'MINUTE',N'SECOND',N'MILLISECOND',N'MICROSECOND',N'NANOSECOND') BEGIN
DECLARE #Error nvarchar(500) = 'Invalid input for Increment Type(''' + #IncrementType + N'''. Valid options are: YEAR, QUARTER, MONTH, DAYOFYEAR, DAY, WEEK, WEEKDAY, HOUR, MINUTE, SECOND, MILLISECOND, MICROSECOND, NANOSECOND.'
RAISERROR(#Error,11,-1);
END ELSE BEGIN
DECLARE #SQL nvarchar(MAX);
SET #SQL = N'SET #dDateStart = DATEADD(' + #IncrementType + N',#dIncrement,#dDateStart)'
PRINT #SQL; --Your best friend
EXEC sp_executesql #SQL, N'#dDateStart date OUTPUT, #dIncrement int', #dDateStart = #DateStart OUTPUT, #dIncrement = #Increment;
END
SELECT #DateStart;
This might be over complicating it, but it's an alternate to the CASE anyway.
implementing inside SSIS:
to get this:
#DateStart = DATEADD(dd,#Increment,#DateStart)
Try this:
#DateStart = #TypeIncrement=="dd" ? DATEADD(dd,#Increment,#DateStart)
: #TypeIncrement=="mm" ? DATEADD(MM,#Increment,#DateStart)
and so on...
If then else is in the format of:
Test ? true part : false part
I use SQL SERVER 2012.
I have stored prcedure:
ALTER PROCEDURE [dbo].[SP_TEST_TLP]
#DateFrom date,
#DateTo date
AS
BEGIN
SET NOCOUNT ON;
select *
from Clients
WHERE DateReview between (#DateFrom) and (#DateTo)
END
As you can see I pass two parameters to stored procedure above and those parameters I use to filter the result in where clause.
My problem is that I need to filter result only by month and year.
For example, if I have passed those parameters:
#DateFrom date = '2016-05-15' ,
#DateTo date = '2016-10-09'
According to stored procedure I will get result between dates above.But I need to get rows from start of the month 05 and end of the month 10 i,e the result should be equivalent to those params:
#DateFrom date = '2016-05-01'
#DateTo date = '2016-10-31'
How can I get the desired result?
You can also use EOMONTH function
select *
from Clients
WHERE DateReview between DATEADD(DAY,1,EOMONTH(#DateFrom,-1) ) and EOMONTH(#DateTO)
Try this :
Here
DATEADD(dd,-(DAY(#DateFrom)-1),#DateFrom) this will give months start date i.e '2016-05-01'
And
DATEADD(dd,-(DAY(DATEADD(mm,1,#DateTo))),DATEADD(mm,1,#DateTo)) will give month end date i.e '2016-10-31'
ALTER PROCEDURE [dbo].[SP_TEST_TLP]
#DateFrom date,
#DateTo date
AS
BEGIN
SET NOCOUNT ON;
SET #DateFrom = DATEADD(dd,-(DAY(#DateFrom)-1),#DateFrom)
SET #DateTo = DATEADD(dd,-(DAY(DATEADD(mm,1,#DateTo))),DATEADD(mm,1,#DateTo))
Updated ---^
select *
from Clients
WHERE DateReview between (#DateFrom) and (#DateTo)
END
Here is one way:
select *
from Clients
where DateReview >= dateadd(day, 1 - day(#DateFrom), #DateFrom) AND
DateReview < dateadd(month, 1, dateadd(day, 1 - day(#DateTo), #DateTo))
This method allows the query to make use of an index on DateReview. You could also do this as:
where year(DateReview) * 100 + month(DateReview)
between year(#DateFrom) * 100 + month(#DateFrom) and
year(#DateTo) * 100 + month(#DateTo)
You can use EOMonth() function
ALTER PROCEDURE [dbo].[SP_TEST_TLP]
#DateFrom date,
#DateTo date
AS
BEGIN
SET NOCOUNT ON;
select *
from Clients
WHERE DateReview between Dateadd(d,1,EOMonth(#DateFrom,-1)) and EOMonnth(#DateTo)
END