Forward dependencies #startdate #enddate=#startdate + 1 Week - sql

Im looking for a way if the user selects
#startdate = '12-01-2015'
then
#enddate = #startdate + 1 Week
this is for my parameter, but please be aware my report is a matrix and uses each week for a sample of data so the parameter needs to automatically select
its enddate from all startdates selected
i.e
startdates in ( '12-01-2015', '19-01-2015')
then endate in ( '18-01-2015', '26-01-2015')
this is what im using for my startdate parameter
select distinct
CAST(startdate AS DATE) as Startdate
FROM [Calendar]
where DatePart(YEAR,startdate) >= 2014
order by 1 asc

Use DATEADD
#startdate = '12-01-2015'
then
#enddate = DATEADD(wk, 1, #startdate)
or if startdate variable has DATE/DATETIME type
#startdate = '12-01-2015'
then
#enddate = #startdate + 7; -- Implicit cast add 7 days
EDIT:
select distinct
CAST(startdate AS DATE) as Startdate,
DATEADD(wk, 1, CAST(startdate AS DATE)) as EndDate
FROM [Calendar]
where DatePart(YEAR,startdate) >= 2014
order by 1 asc

Related

Establishing Date Parameters by Date:Hour instead of just Date

I have the current declared date parameters and "DATE" expression shown below. It provides the data in terms of date only, excluding the 'by hour' detail. I would like to change the below code to add the hour detail to the "DATE" field.
I'm an amateur in terms of SQL, so any suggestions help.
Here is the code...
Declare #Start_Date datetime, #End_Date datetime
set #Start_Date = DATEADD(DAY, DATEDIFF(DAY, '19000101', GETDATE()), '19000101')
set #End_Date = DATEADD(s,-1,DATEADD(dd, DATEDIFF(d,0,GETDATE())+7,0))
;
--Common Table Express1on (CTE) to get dates*****
With DateSequence( [Date] ) as
( Select #Start_Date as [Date]
union all
Select dateadd(day, 1, [Date])
from DateSequence
where Date < #End_Date)
Thanks in advance!
-Matt
Just add 1 hour instead of 1 day:
with DateHourSequence as (
select #Start_Date as yyyymmddhh
union all
select dateadd(hour, 1, yyyymmddhh)
from DateHourSequence
where yyyymmddhh < #End_Date
)

Recursive CTE Returns Value Outside of Range

While searching for a method to create date ranges I came across a problem with the following query:
DECLARE #StartDate DateTime = '2000-01-01 01:00';
DECLARE #EndDate DateTime = '2020-01-01 00:00';
with Dates as (
select
#StartDate fromDate
UNION ALL
(Select
fromDate = dateadd(day, 1, #EndDate)
from
Dates
where
fromDate >= #StartDate AND
fromDate < #EndDate ))
Select * from Dates
OPTION (MAXRECURSION 0);
The following query returns two rows, one of which is outside of the range,
fromDate
-----------------------
2000-01-01 01:00:00.000
2020-01-02 00:00:00.000
I am aware that there is a way to fix this issue by changing the second half of the query to be different, for example:
Select * from Dates Where fromDate <= #EndDate
I have the following questions:
what is wrong with the query as is?
Why is it that this query returns two values, one of which lies outside the range provided?
This is using Microsoft SQL Server 2008 R2
Because your Recursive CTE add one day from fromDate
Select
fromDate = dateadd(day, 1, #EndDate)
but your condition filter fromDate
where
fromDate >= #StartDate AND
fromDate < #EndDate ))
If you want to do make calendar table by Recursive CTE.
you can try this.
with Dates as (
select #StartDate fromDate,#EndDate endDate
UNION ALL
Select
fromDate = dateadd(day, 1, fromDate),endDate
from
Dates
where
dateadd(day, 1, fromDate) <= #EndDate
)
Select * from Dates
OPTION (MAXRECURSION 0);
The simple answer for #1 / #2: You are selecting DATEADD(day, 1, #endDate) -- which, by definition, is 1 day 'over' your date range.
The real answer: To get the result you want, change:
(Select
fromDate = dateadd(day, 1, #EndDate)
To:
(Select
fromDate = dateadd(day, 1, fromDate)

compute start date of sub-date-range from given main date range in sql server

input is a main date range which is stored in myTbl.StartDate and myTbl.EndDate columns values.
for a given constant value as divider, I need to compute start date of sub-date-ranges gained from dividing main date range to sub-date-ranges with constant value length.
examples are best explanations:
for main date range between '2017-1-1' to '2017-1-22' and const_val = 6 output is:
2017-1-1
2017-1-7 (1 + 6)
2017-1-13 (7 + 6)
2017-1-19 (13 + 6)
its noticable that the SQL user is not administrator(I can't use system tables)
You can use a recursive cte to do this:
DECLARE #startDate DATE = '20170101' ,
#endDate DATE = '20170122' ,
#Const_val INT = 6;
WITH cte
AS ( SELECT #startDate AS DateVal
UNION ALL
SELECT DATEADD(DAY, #Const_val, cte.DateVal)
FROM cte
WHERE DATEADD(DAY, #Const_val, cte.DateVal) <= #endDate
)
SELECT *
FROM cte;
Produces:
DateVal
==========
2017-01-01
2017-01-07
2017-01-13
2017-01-19
The first part of the cte gets the first date:
SELECT #startDate AS DateVal
Then it adds 6 days with the UNION ALL until the WHERE condition is met.
You can try the following:
DECLARE #StartDate DATE = CONVERT(date, '2017-01-01');
DECLARE #EndDate DATE = CONVERT(date, '2017-01-22');
DECLARE #FixDateDiff int = 6;
WITH cte AS (
SELECT #StartDate AS MyDate
UNION ALL
SELECT DATEADD(d, 1, MyDate)
FROM cte
WHERE DATEADD(d, 1, MyDate) <= CONVERT(date, #EndDate)
)
SELECT MyDate
FROM cte
WHERE DATEDIFF(d, #StartDate, MyDate)%#FixDateDiff = 0
However, instead of the fixed dates I assigned to the variables, simply replace the variables with your StartDate and EndDate column and extend the cte accordingly.

SQL- How to split two dates into yearly format

If I have two dates for example:
#StartDate = '2009/01/01'
#EndDate = '2015/02/05'
is there a way for it to display in this format:
StartDate EndDate
2009/01/01 2010/01/01
2010/01/01 2011/01/01
2011/01/01 2012/01/01
2012/01/01 2013/01/01
2013/01/01 2014/01/01
2014/01/01 2015/01/01
2015/01/01 2015/02/05 <--- most importantly end using the end date
is this possible? because I have seen a number of CTE code snippets but they only split upto 01/01/2015 and not continue to the end of period 05/02/2015? Is there any possible chance for it include the remainder of the final period - 2015/01/01 - 2015/02/05 even though its not a year?
Here is a way:
with nums as (
select 0 as n
union all
select 1 + n
from nums
where n < 100
)
select DATEADD(year, n, #StartDate) as StartDate,
(case when DATEADD(year, n+1, #StartDate) >= #EndDate then #EndDate
else DATEADD(year, n+1, #StartDate)
end) as EndDate
from nums
where dateadd(year, nums.n, #StartDate) < #EndDate
If your periods are really long, you might need to expand nums beyond 100 values.
DECLARE #StartDate DATETIME = '2009/01/01'
DECLARE #EndDate DATETIME = '2015/02/05'
;WITH Dates AS
(
SELECT
StartDate = #StartDate,
EndDate = DATEADD(YEAR, 1, #StartDate)
UNION ALL
SELECT
StartDate = DATEADD(YEAR, 1, StartDate),
EndDate = CASE
WHEN DATEADD(YEAR, 1, EndDate) > #EndDate
AND DATEADD(YEAR, -1, EndDate) < DATEADD(YEAR, -1, #EndDate) THEN #EndDate
ELSE DATEADD(YEAR, 1, EndDate)
END
FROM Dates
WHERE EndDate < #EndDate
)
SELECT * FROM dates
OPTION (MAXRECURSION 0)
demo

Compare current date with stored datetime using month an year only

Using SQL Server 2005 I have a field that contains a datetime value.
What I am trying to do is create 2 queries:
Compare to see if stored datetime is of the same month+year as current date
Compare to see if stored datetime is of the same year as current date
There is probably a simple solution but I keep hitting brick walls using various samples I can find, any thoughts?
Thanks in advance.
Compare the parts of the date:
WHERE YEAR( columnName ) = YEAR( getDate() )
While the other answers will work, they all suffer from the same problem: they apply a transformation to the column and therefore will never utilize an index on that column.
To search the date without a transformation, you need a couple built-in functions and some math. Example below:
--create a table to hold our example values
create table #DateSearch
(
TheDate datetime not null
)
insert into #DateSearch (TheDate)
--today
select getdate()
union all
--a month in advance
select dateadd(month, 1, getdate())
union all
--a year in advance
select dateadd(year, 1, getdate())
go
--declare variables to make things a little easier to see
declare #StartDate datetime, #EndDate datetime
--search for "same month+year as current date"
select #StartDate = dateadd(month, datediff(month, 0, getdate()), 0), #EndDate = dateadd(month, datediff(month, 0, getdate()) + 1, 0)
select #StartDate [StartDate], #EndDate [EndDate], TheDate from #DateSearch
where TheDate >= #StartDate and TheDate < #EndDate
--search for "same year as current date"
select #StartDate = dateadd(year, datediff(year, 0, getdate()), 0), #EndDate = dateadd(year, datediff(year, 0, getdate()) + 1, 0)
select #StartDate [StartDate], #EndDate [EndDate], TheDate from #DateSearch
where TheDate >= #StartDate and TheDate < #EndDate
What the statement does to avoid the transformations, is find all values greater-than or equal-to the beginning of the current time period (month or year) AND all values less-than the beginning of the next (invalid) time period. This solves our index problem and also mitigates any issues related to 3ms rounding in the DATETIME type.
SELECT * FROM atable
WHERE
YEAR( adate ) = YEAR( GETDATE() )
AND
MONTH( adate ) = MONTH( GETDATE() )
It sounds to me like DATEDIFF is exactly what you need:
-- #1 same month and year
SELECT *
FROM your_table
WHERE DATEDIFF(month, your_column, GETDATE()) = 0
-- #2 same year
SELECT *
FROM your_table
WHERE DATEDIFF(year, your_column, GETDATE()) = 0
The datepart function lets you pull the bits you need:
declare #d1 as datetime
declare #d2 as datetime
if datepart(yy, #d1) = datepart(yy, #d2) and datepart(mm, #d1) = datepart(mm, #d2) begin
print 'same'
end
You can use something like this
a)
select *
from table
where MONTH(field) = MONTH(GetDATE())
and YEAR(field) = YEAR(GetDATE())
b)
select *
from table
where YEAR(field) = YEAR(GetDATE())