I have a date dimension table, which has for each date record a large number of fields, one of which is the fortnight of year.
I am trying to write a T-SQL query to return the last date of the previous fortnight and the previous fortnight number, based on the current date (or any date passed to it).
I can get the current fortnight and last date ok, what I need to figure out is how to get the previous fortnight end date, including over the transition to a new year.
The code I have below works to return the current fortnight of the year and the last date of that fortnight, how would I modify this to return the previous fortnight and end date of that fortnight for any date, particularly if the date was say the 2nd Jan in any year?
With
Query1 As
(Select
Cast(GetDate() As Date) As Todays_Date)
Select
Query1.Todays_Date,
staging.dbo.manualdata_DateDimension.FortnightofYear,
Max(staging.dbo.manualdata_DateDimension.Date) As Max_Date
From
Query1 Inner Join
staging.dbo.manualdata_DateDimension On staging.dbo.manualdata_DateDimension.Date = Query1.Todays_Date
Group By
Query1.Todays_Date,
staging.dbo.manualdata_DateDimension.FortnightofYear
Try something like this:
WITH DataSource AS
(
SELECT FortnightofYear
,Date
,GETDATE() AS [Todays_date]
,ROW_NUMBER() PARTITION BY (FortnightofYear ORDER BY Date DESC) AS [RowID]
,LAG(Date) PARTITION BY (FortnightofYear ORDER BY Date DESC) AS [PreviosDate]
FROM staging.dbo.manualdata_DateDimension
WHERE Date <= GETDATE()
)
SELECT *
FROM DataSource
WHERE ([RowID] = 1 AND Date = [Todays_date])
OR ([RowID] = 2 AND [PreviosDate] = [Todays_date])
Try this. It assumes FortnightofYear
starts over every year from 1
DECLARE @DateToSearch datetime = GetDate() ---- set this to the date to be searched
; WITH cte AS (
SELECT
t.Year
, t.FortnightofYear
, FirstDate = MIN(t.Date)
, LastDate = MAX(t.Date)
FROM
staging.dbo.manualdata_DateDimension t
GROUP BY
t.Year
, t.FortnightofYear
)
SELECT
Todays_Date = @DateToSearch
, Current_FortnightofYear = FortnightofYear
, Current_FortnightofYear_First_Date = FirstDate
, Current_FortnightofYear_Last_Date = LastDate
--- if no previous records, values will be NULL
, Previous_FortnightofYear = LAG(FortnightofYear, 1, NULL) OVER (ORDER BY Year, FortnightofYear)
, Previous_FortnightofYear_First_Date = LAG(First_Date, 1, NULL) OVER (ORDER BY Year, FortnightofYear)
, Previous_FortnightofYear_Last_Date = LAG(Last_Date, 1, NULL) OVER (ORDER BY Year, FortnightofYear)
FROM
cte
WHERE
@DateToSearch BETWEEN FirstDate AND LastDate
Thanks to both gotqn and K4M as it made me rethink how I was going about it, but neither post worked.
Here is the code that returns the required data (I hope I have tagged it correctly), passing @rundate on execution as any date.
With
Query1 As (
Select
staging.dbo.manualdata_DateDimension.Year,
staging.dbo.manualdata_DateDimension.FortnightofYear,
Min(staging.dbo.manualdata_DateDimension.Date) As min_date,
Max(staging.dbo.manualdata_DateDimension.Date) As max_date,
Cast(DateAdd(Day, DateDiff(Day, 1, Min(staging.dbo.manualdata_DateDimension.Date)), 0) As date) As
previous_fortnight_max_date
From
staging.dbo.manualdata_DateDimension
Group By
staging.dbo.manualdata_DateDimension.Year,
staging.dbo.manualdata_DateDimension.FortnightofYear
Having
@rundate Between Min(staging.dbo.manualdata_DateDimension.Date) And
Max(staging.dbo.manualdata_DateDimension.Date)
)
Select
Query1.Year,
Query1.FortnightofYear,
Query1.min_date,
Query1.max_date,
Query1.previous_fortnight_max_date,
staging.dbo.manualdata_DateDimension.FortnightofYear As PreviousFortnightofYear
From
Query1 Inner Join
staging.dbo.manualdata_DateDimension On staging.dbo.manualdata_DateDimension.Date =
Query1.previous_fortnight_max_date
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.