我正在寻找一些T-SQL代码,它应该选择的日期是"从当前日期开始的一年(在1月份的最后一个星期日的同一时间)"。
我有一些在SQL Server 2014中使用的T-SQL代码:
select
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
以上代码选择当前年份的日期(1月份的最后一个星期日)。但我希望T-SQL代码可以选择去年(上个星期日和1月份的日期)日期。
详细说明 - 我希望T-SQL代码从下表中生成预期结果
Current day Expected result
---------------------------------------
2017-02-05 2016-01-31
2017-01-05 2015-01-25
2018-02-19 2017-01-29
2018-01-19 2016-01-31
2019-02-28 2018-01-28
请注意,年份始于" 1月份的最后一个星期日"。
答案 0 :(得分:3)
将会有更简洁的解决方案,但是当我们假设您的代码经过时间考验并且功能强大时,我只需将GETDATE()
替换为现在减去一年的表达式:
DATEADD(year, -1, GETDATE())
因此:
SELECT
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
答案 1 :(得分:3)
如果您有日历表,则可以跳过第一个CTE(可能还有MAXRECURSION
选项)并只使用日历表。希望这明确正确:
declare @today date
set @today = CURRENT_TIMESTAMP
;With Dates as (
select CONVERT(date,'19000101') as d
union all
select DATEADD(day,1,d) from Dates where d < '21000101'
), ApplicableSundays as (
select d,ROW_NUMBER() OVER (ORDER BY d desc) as rn
from Dates
where d < @today and
DATEPART(month,d) = 1 and
DATEPART(weekday,d) = DATEPART(weekday,'20150913') and --Any known Sunday
DATEPART(day,d) between 25 and 31
)
select d
from ApplicableSundays where rn = 2
option (maxrecursion 0)
Dates
生成了20世纪和21世纪的所有日期,这有希望足够灵活用于您的目的。
ApplicableSundays
将这些行过滤到@today
之前的日期,即1月份,是星期日(使用已知良好的日期,而不是依赖于任何特定的DATEFIRST
设置)并且在那个月的25日和31日之间。
如果我们的年份从每年一月的最后一个星期日开始,那么我们选择这些日期中的第二个日期,这必须是去年的开始。
如果你正在反对一个满桌的日程表,你希望找到这个日期,并且去年开始#34;值,您可以在join
CTE中将其作为ApplicableDates
引入,并使用这些值对ROW_NUMBER()
聚合进行分区,以便您可以并行查找所有星期日。
答案 2 :(得分:0)
这将使用数据隔离列。
请试试让我知道。感谢。
select
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4),
GetDate(), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120) AS CurrentDay , convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4),
DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120) as ExpectedResult