October 30, 2005 at 3:10 pm
I want a SELECT statement giving all the dates in a range.
I.e.
I have two records (ID, DateFrom, DateTo), no time-part, dates in ISO-notation:
1 2005/10/28 2005/10/30
2 2005/10/15 2005/10/16
This is what I want as result from a SELECT statement
2005/10/30
2005/10/29
2005/10/28
2005/10/16
2005/10/15
Is this possible?
October 30, 2005 at 4:32 pm
You want something like:
SELECT [DateFrom]
FROM MyTable
UNION
SELECT [DateTo]
FROM MyTable
You could add DISTINCT to the SELECT if you only wanted to return one of each date (if you had more than the 2 rows in your example).
October 30, 2005 at 4:35 pm
Select t2.Date from Table2 t2
inner join Table1 t1 on t2.date between t1.DateFrom and t1.DateTo
GROUP BY t2.Date
ORDER BY t2.Date DESC
_____________
Code for TallyGenerator
October 30, 2005 at 7:02 pm
I think what Henk want is the select statement to return all dates between the DateFrom and DateTo.
Record 1 : 2005/10/28 to 2005/10/30
will return dates 2005/10/28, 2005/10/29, 2005/10/30.
Henk, Please correct if this not what you need.
I don't think a single select statement can return date (2005/10/29) not existed in a table.
The only solution i can think of is using while loop. Alternatively have a table pre-populated with all dates and join your table with that all dates table.
Any one else have better solution ?
October 31, 2005 at 1:35 am
KH, exactly what you said:
"I want a select statement to return all dates between the DateFrom and DateTo".
I think I have to make a table pre-populated with all dates (from now till the end of time) and join it with my DateFrom/DateTill - table.
Any one else have better solution ?
October 31, 2005 at 6:16 am
"The difficult can be done immediately... the impossible takes slightly longer."
This will work but the creation of a real "Numbers" table would be better as it would be more predictable and the performance would be much better...
SELECT DATEADD(dd,N,StartDate) AS TheDate
FROM yourtable y,
(--Derived table returns numbers from 0 to at least 255
--and takes the place of a short "numbers" table
SELECT (
SELECT COUNT(*)
FROM dbo.SYSOBJECTS son
WHERE son.ID < so.ID
) AS N
FROM dbo.SYSOBJECTS so
) Numbers
WHERE Numbers.N <= DATEADD(dd,DATEDIFF(dd,StartDate,EndDate),0)
ORDER BY TheDate DESC
The SYSOBJECTS table will always have at least 256 entries even on a band-spanking-new database... that would be you normal limit for how many days are between your start and end dates...
Like I said, it would be far better to create a real numbers table.
--Jeff Moden
Change is inevitable... Change for the better is not.
October 31, 2005 at 11:50 am
Jeff, as you say:
"The difficult can be done immediately... the impossible takes slightly longer."
Thank you for showing me the slightly longer solution It's a beautiful solution, even comical.
But, ... as I need only 6 weeks (42 days) your DATEADD approach with a real number table (0..41) will be satisfactory. Thanks a lot
October 31, 2005 at 2:04 pm
Hi,
I had a similar task to return all values where I had a table with StartValue and EndValue fields
I created a cursor, here is a code idea. I had to deal with Integers, In your case you will have to use datediff and dateadd functions to get integer numbers per other posts above.
<all declarations first> then:
Declare curAD Cursor
For
Select StartValue, Endvalue From mytable
Order By StartValue
Open curAD
Fetch From curAD
Into @ValueStart,@ValueEnd
WHILE @@FETCH_STATUS = 0
BEGIN
SET @i = @ValueStart
WHILE @i < @ValueEnd + 1
BEGIN
Insert NewTable(Value)
Values (@i)
SET @i = @i + 1
END
Fetch Next From curAD
Into @ValueStart,@ValueEnd
END
Close curAD
Deallocate CurAD
Regards,Yelena Varsha
October 31, 2005 at 2:20 pm
Yelena, thank you.
I never wordked with a cursor, I am more used to select statements, but it is nice to see this solution (now I see what KH ment, when he mentioned "using a while loop").
October 31, 2005 at 2:53 pm
Henk,
Cursors are very close to Recordsets with a very similar syntax. I use cursors if performance is not a problem because their performance is not as good as Select statement. But sometimes it is easier to use a cursor logic: get the first row into the local variables, do the processing including getting values from the startvalue to the endvalue and inserting these values into another table or temp table. When completing processing of the first pair fetch next - load the second row into the same variables. Continue untill Fetch Status (@@Fetch_Status) is not null anymore which means end of recordset.
I use examples from Books Online and modify them for my tasks. Do not forget to Close and Deallocate the cursors to reclaim memory.
Regards,Yelena Varsha
October 31, 2005 at 5:24 pm
You bet, Henk... thank you for the feed back.
I gotta know... what's comical about it?
--Jeff Moden
Change is inevitable... Change for the better is not.
October 31, 2005 at 6:44 pm
For reference:
Why should I consider using an auxiliary numbers table?
http://www.aspfaq.com/show.asp?id=2516
See the section on usage of the numbers stable to generate date ranges:
When you need to generate a set of dates in a range, the typical solution is to create a loop and iterate through the range, adding a day each time. However, a numbers table can help us generate this range as a set, instead of treating each date in the range individually. This way, you can use the code directly in a subquery or in a table-valued function, without having to worry about creating a temporary table to hold the values while you iterate through the loop.
DECLARE @sDate SMALLDATETIME, @eDate SMALLDATETIME
SET @sDate = '20040101'
SET @eDate = '20040229'
SELECT @sDate + Number
FROM dbo.Numbers
WHERE @sDate + Number <= @eDate
ORDER BY 1
SQL = Scarcely Qualifies as a Language
October 31, 2005 at 6:45 pm
For reference:
Why should I consider using an auxiliary numbers table?
http://www.aspfaq.com/show.asp?id=2516
See the section on usage of the numbers stable to generate date ranges:
When you need to generate a set of dates in a range, the typical solution is to create a loop and iterate through the range, adding a day each time. However, a numbers table can help us generate this range as a set, instead of treating each date in the range individually. This way, you can use the code directly in a subquery or in a table-valued function, without having to worry about creating a temporary table to hold the values while you iterate through the loop.
DECLARE @sDate SMALLDATETIME, @eDate SMALLDATETIME
SET @sDate = '20040101'
SET @eDate = '20040229'
SELECT @sDate + Number
FROM dbo.Numbers
WHERE @sDate + Number <= @eDate
ORDER BY 1
SQL = Scarcely Qualifies as a Language
October 31, 2005 at 6:47 pm
For reference:
Why should I consider using an auxiliary numbers table?
http://www.aspfaq.com/show.asp?id=2516
See the section on usage of the numbers stable to generate date ranges:
When you need to generate a set of dates in a range, the typical solution is to create a loop and iterate through the range, adding a day each time. However, a numbers table can help us generate this range as a set, instead of treating each date in the range individually. This way, you can use the code directly in a subquery or in a table-valued function, without having to worry about creating a temporary table to hold the values while you iterate through the loop.
DECLARE @sDate SMALLDATETIME, @eDate SMALLDATETIME
SET @sDate = '20040101'
SET @eDate = '20040229'
SELECT @sDate + Number
FROM dbo.Numbers
WHERE @sDate + Number <= @eDate
ORDER BY 1
SQL = Scarcely Qualifies as a Language
November 2, 2005 at 1:44 am
Yelena, thank you for the extended explanation.
But I used the code of Jef and Carl because it fits the best in the way I have to use these date. I always need (6 weeks = ) 42 days (from a Numbers table Nrs Field Nr 0..41) left outer joined with a table with start and end-dates. This From the first Monday before the start of the month (eg 2005-08-29 before the month september)
SELECT Dat, COALESCE(ISDATE(DatFrom), 0) AS Free
FROM (SELECT DATEADD(dd, Nr, '20050829') AS Dat FROM Nrs) AS D LEFT OUTER
JOIN DatPeriods DP ON D.Dat BETWEEN DatFrom AND DatTill
ORDER By Dat
It gives me 42 dates with Free 0 or 1
Ie:
Dat Free
2005-08-29 1
2005-08-30 1
2005-08-31 1
2005-09-01 1
2005-09-02 0
2005-09-03 0
2005-09-04 0
2005-09-05 1
2005-09-06 1
2005-09-07 1
etc.
Viewing 15 posts - 1 through 15 (of 15 total)
You must be logged in to reply to this topic. Login to reply