基於在這個答案中發佈的想法here我創建了以下模式和查詢來計算正確的日期。
該查詢將被轉換爲內嵌表值函數,該函數將接受@Id
和@RelativeToDate
的參數。
DayOfWeekNumber
將保持1-7的值,其中1 =星期一,7 =星期日,函數應該計算正確的結果,而不管@@DATEFIRST
。
目前在表格中沒有指定約束條件,但確實應該確保表格中只存在有效條目。
DECLARE @RelativeDate TABLE
(
Id INT IDENTITY(1,1)
, Name VARCHAR(100)
, DayOfWeekNumber TINYINT
, DayOfMonthNumber TINYINT
, LastDayOfMonth BIT
, DayOffset SMALLINT
, WeekOffset SMALLINT
, MonthOffset SMALLINT
, YearOffset SMALLINT
)
INSERT INTO @RelativeDate
(
Name
, DayOfWeekNumber
, DayOfMonthNumber
, LastDayOfMonth
, DayOffset
, WeekOffset
, MonthOffset
, YearOffset
)
VALUES
('1st of previous month', 0, 1, 'FALSE', 0, 0, -1, 0)
, ('Last of previous month', 0, 0, 'TRUE', 0, 0, -1, 0)
, ('1st of current month', 0, 1, 'FALSE', 0, 0, 0, 0)
, ('Last of current month', 0, 0, 'TRUE', 0, 0, 0, 0)
, ('7th of current month', 0, 7, 'FALSE', 0, 0, 0, 0)
, ('8th of current month', 0, 8, 'FALSE', 0, 0, 0, 0)
, ('14th of current month', 0, 14, 'FALSE', 0, 0, 0, 0)
, ('21th of current month', 0, 21, 'FALSE', 0, 0, 0, 0)
, ('22th of current month', 0, 22, 'FALSE', 0, 0, 0, 0)
, ('28th of current month', 0, 28, 'FALSE', 0, 0, 0, 0)
, ('29th of current month', 0, 29, 'FALSE', 0, 0, 0, 0)
, ('This Sunday', 7, 0, 'FALSE', 0, 0, 0, 0)
, ('Next Sunday', 7, 0, 'FALSE', 0, 1, 0, 0)
, ('Last Sunday', 7, 0, 'FALSE', 0, -1, 0, 0)
DECLARE
@Date DATE = GETDATE()
SELECT
*
, DATENAME(WEEKDAY, DateValue) AS WeekDayName
FROM
@RelativeDate
CROSS APPLY(VALUES(
DATEADD(DAY, DayOffset,
DATEADD(WEEK, WeekOffset,
DATEADD(MONTH, MonthOffset,
DATEADD(YEAR, YearOffset, @Date))))
)) AS OffsetDate(OffsetDate)
CROSS APPLY(VALUES(
CASE
WHEN LastDayOfMonth = 'TRUE'
THEN DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, OffsetDate) + 1, 0))
-- If the month doesn't have the day of the month number then return NULL
WHEN DayOfMonthNumber <> 0 AND DayOfMonthNumber > DATEPART(DAY, DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, OffsetDate) + 1, 0)))
THEN NULL
WHEN DayOfMonthNumber <> 0 AND DATEPART(DAY, OffsetDate) > DayOfMonthNumber
THEN DATEADD(DAY, DayOfMonthNumber - DATEPART(DAY, OffsetDate), OffsetDate)
WHEN DayOfMonthNumber <> 0 AND DATEPART(DAY, OffsetDate) < DayOfMonthNumber
THEN DATEADD(DAY, DayOfMonthNumber - DATEPART(DAY, OffsetDate), OffsetDate)
WHEN DayOfWeekNumber <> 0
THEN DATEADD(DAY, DayOfWeekNumber - (((DATEPART(WEEKDAY, OffsetDate) + @@DATEFIRST - 1 - 1) % 7) + 1), OffsetDate)
END
)) AS DateValue(DateValue)
我不確定我是否理解這裏的問題?你想知道如何找到像上個月的最後一天那樣的事情嗎?這裏是一些常見的日期時間例程的鏈接。 http://www.sqlservercentral.com/blogs/lynnpettis/2009/03/25/some-common-date-routines/ – 2015-02-11 15:31:21
請參閱更新的問題。 – mheptinstall 2015-02-11 19:16:26
表示相對日期的一種方式:http://programmers.stackexchange.com/a/78883/111526 – mheptinstall 2015-02-11 19:39:56