简体   繁体   中英

T-SQL Last date of previous fortnight, catering for year transition

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM