Years.Year
Weeks.WeekNumber
http://whatweekisit.org/ 现在我要创建一个视图,根据参数Years.Year
和Weeks.WeekNumber
下面的代码获取周数,但是请正确计算日期:
SET DATEFIRST 4
DECLARE @d DATETIME
SET @d = GETDATE()
--BELOW IS WHAT I WANT TO WORK ALTHOUGH THE SUB QUERY RETURNS MORE THAN ONE VALUE
--(SELECT Weeks.WeekNumber FROM Weeks)
SELECT
Weeks.WeekNumber,
DATEADD(dd, (@@DATEFIRST + 5 + DATEPART(dw, @d)) % 7, @d) Monday
FROM Weeks
示例数据:
Week Number Date
1 29/12/2014
2 05/01/2015
3 12/01/2015
4 19/01/2015
5 26/01/2015
... ...
53 28/12/2015
总结:
2015年包含53个星期一,因此我尝试生成一个SELECT语句,该语句将指定周数和每周的日期,就像上面的示例数据一样
感谢下面的帮助,以及各种日历表的建议....我会尝试测试所有:)
答案 0 :(得分:2)
这不会使用您的查找表,但会生成一年中每个星期一的日期表(仅经过轻微测试):
DECLARE @year INT = DATEPART(YEAR, GETDATE())
DECLARE @firstDate DATE = CONVERT(VARCHAR(12), @year) + '0101'
SET DATEFIRST 1;
WITH cte
AS ( SELECT 1 AS WeekNo ,
DATEADD(DD, 1 - DATEPART(DW, @firstDate), @firstDate) AS MonDate
UNION ALL
SELECT cte.WeekNo + 1 ,
DATEADD(DAY, 7, cte.MonDate) AS MonDate
FROM cte
WHERE DATEPART(YEAR, DATEADD(DAY, 7, cte.MonDate)) = @year
)
SELECT *
FROM cte
它会计算给定年份的第一个星期一,然后只需将7天添加到年底。
答案 1 :(得分:2)
你可以试试这样的事情
DECLARE @startDate DATETIME
DECLARE @endDate DATETIME
SET @startDate = DATEADD(DAY, 1-DATEPART(WEEKDAY, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP)
SET @endDate = '2016-1-31';
WITH dates(Date) AS
(
SELECT @startdate as Date
UNION ALL
SELECT DATEADD(d,7,[Date])
FROM dates
WHERE DATE < @enddate
)
SELECT Date
FROM dates
OPTION (MAXRECURSION 0)
答案 2 :(得分:2)
你可以写成:
-- SET DATEFIRST to U.S. English default value of 7.
SET DATEFIRST 7;
SELECT DATEPART( wk, [DateofYear]) as [Week Number],
[DateofYear] as[MondayDate]
FROM (
SELECT TOP (365)
DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY number)-1, '20150101') AS [DateofYear]
FROM [master].dbo.spt_values
WHERE [type] = N'P' ORDER BY number
) AS T
WHERE datepart(dw,[DateofYear]) = 2 --Monday
ORDER BY [DateofYear];
答案 3 :(得分:2)
请尝试这个: -
Declare @StartDate Date = '2015-01-01'
---- here consider Your Week table as AllWeeks
;With AllWeeks As
(
Select 1 As WeekNo
Union All
Select (WeekNo + 1)
From AllWeeks As w
Where w.WeekNo < 53
)
Select w.WeekNo
,Dateadd(Day, (2 - Datepart(DW, Dateadd(Week, w.WeekNo, @StartDate))), Dateadd(Week, w.WeekNo, @StartDate)) As Mondays
From AllWeeks As w
Where Datepart(Year, Dateadd(Day, (2 - Datepart(DW, Dateadd(Week, w.WeekNo, @StartDate))), Dateadd(Week, w.WeekNo, @StartDate))) = 2015
答案 4 :(得分:2)
正如评论中所提到的,如果您自己构建calendar table,这会更容易,您的查询只会是:
DECLARE @Year INT = 2015;
SELECT Date, ISOWeek
FROM CalendarTable
WHERE DayNumberOfWeek = 1
AND ISOYear = @Year;
我会假设这不是你的选择。第一步是获得一年中的第一天,这很简单:
SELECT CAST(CAST(@Year AS VARCHAR(4)) + '0101' AS DATE)
然后你可以得到本周的星期一:
SELECT DATEADD(WEEK, DATEDIFF(WEEK, 0, YearStart), 0)
然后你从1到53的一组数字来添加你的周数:
SELECT TOP(53) ROW_NUMBER() OVER(ORDER BY object_id)
FROM sys.all_objects
最后,如果今年的第一天是在今年的第一周或去年的最后一周,你需要确定。如果是后者,那么您需要在周开始计算中添加一周。结合以上内容,你得到:
DECLARE @Year INT = 2016;
SELECT n.Weeknumber,
StartOfWeek = DATEADD(WEEK, DATEDIFF(WEEK, 0, d.YearStart) + n.WeekNumber + n.Factor, 0)
FROM (SELECT CAST(CAST(@Year AS VARCHAR(4)) + '0101' AS DATE)) AS d (YearStart)
CROSS APPLY
( SELECT TOP(53) ROW_NUMBER() OVER(ORDER BY object_id),
CASE WHEN DATEPART(ISO_WEEK, d.YearStart) = 1 THEN -1 ELSE 0 END
FROM sys.all_objects
) AS n (Weeknumber, Factor)
WHERE DATEPART(ISO_WEEK, DATEADD(WEEK, DATEDIFF(WEEK, 0, YearStart) + n.WeekNumber + n.Factor, 0)) = n.WeekNumber;
最后的where子句将删除上周,以确保在52周内您不会包含下一年的第一周。
修改强>
刚刚意识到你已经有了53个数字的表格,所以你不需要自己生成:
DECLARE @Year INT = 2016;
SELECT w.Weeknumber,
StartOfWeek = DATEADD(WEEK, DATEDIFF(WEEK, 0, d.YearStart) + w.WeekNumber + f.Factor, 0)
FROM (SELECT CAST(CAST(@Year AS VARCHAR(4)) + '0101' AS DATE)) AS d (YearStart)
CROSS JOIN Weeks AS w
CROSS APPLY (SELECT CASE WHEN DATEPART(ISO_WEEK, YearStart) = 1 THEN -1 ELSE 0 END) f (Factor)
WHERE DATEPART(ISO_WEEK, DATEADD(WEEK, DATEDIFF(WEEK, 0, d.YearStart) + w.WeekNumber + f.Factor, 0)) = w.WeekNumber;
答案 5 :(得分:2)
检查一下:
;WITH Recur AS
(
SELECT CAST('1/1/' + CAST(YEAR(GETDATE()) AS VARCHAR) AS DATETIME) AS RecurDate
UNION ALL
SELECT DATEADD(DAY, 1, RecurDate)
FROM Recur
WHERE YEAR(RecurDate) = YEAR(GETDATE())
)
SELECT
CONVERT(VARCHAR, RecurDate, 103) AS [Date]
FROM
Recur
WHERE DATENAME(WEEKDAY,RecurDate) = 'Monday'
OPTION (MAXRECURSION 0)
答案 6 :(得分:1)
也许是这样的?
DECLARE @year INT=2015;
WITH ThreeHundredSixtySixNumbers AS
(
SELECT TOP 366 ROW_NUMBER() OVER(ORDER BY object_id) As nmbr
FROM sys.objects --any large table with at least 366 rows
)
,FirstDayOfYear AS
(
SELECT CAST(CONVERT(VARCHAR(4),@year) + '/1/1' AS DATE) AS FirstDay
)
,MondayOnly AS
(
SELECT nmbr AS DayIndex
FROM ThreeHundredSixtySixNumbers
WHERE ((nmbr - DATEPART(WEEKDAY,(SELECT FirstDay FROM FirstDayOfYear)))%7) = 0
)
SELECT ROW_NUMBER() OVER(ORDER BY DayIndex) AS WeekNumber
,DATEADD(DAY,DayIndex,(SELECT FirstDay FROM FirstDayOfYear))
FROM MondayOnly