我有一个日期表,其列定义为一周的第一天。该值始终为该月的第一天或周四。我被困住的地方是在前一行中重复一周的第一天,以便我可以正确地对数据进行分组。该表看起来像这样
因此对于2014年1月3日 - 2014年1月8日的日期,我需要填写1/2/2014作为FirstDateOfWeekFullDate,以此类推,以便在一周的下一个第一天使用。
非常感谢任何帮助
答案 0 :(得分:1)
在sql-server和其他支持LAG窗口功能的平台上,你可以得到你想要的结果(通过选择),如下所示:
SELECT FullDate, CalendarYear, IsFirstDayOfWeek,
COALESCE(FirstDateOfWeekFullDate,
LAG(FirstDateOfWeekFullDate,1) OVER (ORDER BY FullDate ASC),
LAG(FirstDateOfWeekFullDate,2) OVER (ORDER BY FullDate ASC),
LAG(FirstDateOfWeekFullDate,3) OVER (ORDER BY FullDate ASC),
LAG(FirstDateOfWeekFullDate,4) OVER (ORDER BY FullDate ASC),
LAG(FirstDateOfWeekFullDate,5) OVER (ORDER BY FullDate ASC),
LAG(FirstDateOfWeekFullDate,6) OVER (ORDER BY FullDate ASC))
as FirstDateOfWeekFullDate
FROM putYourTableNameHere
您也可以通过加入来完成。我认为LAG会更快 - 但我说这个没有测试两者。
答案 1 :(得分:1)
由于它与FullDate
中的值相关,您可以使用CASE
语句根据该字段中的值修改结果。这样的事情应该有效:
SELECT
FullDate,
CalendarYear,
IsFirstDayOfWeek,
CASE WHEN datepart(DW,FullDate) > 5 THEN FullDate - datepart(DW,FullDate) + 5
WHEN datepart(DW,FullDate) < 5 THEN FullDate - datepart(DW,FullDate) - 2
ELSE FullDate END as [FirstDateOfWeekFullDate]
FROM YourDB..YourTable
这在T-SQL中有效。我不确定您使用的是哪种RDBMS,但所有这些功能都有相似的功能。
修改强>
包含该月的第一天有点复杂,但仍然可以使用案例陈述。下面的CASE
示例检查FullDate值是否大于或等于当前月份的第5个星期四(如果存在5),然后是第4个星期四,然后是第3个星期四,然后是第2个星期四,然后是1。如果它小于第一个星期四的日期值,那么它默认为该月的第一天,无论它是什么工作日。
它看起来像很多代码,但它实际上只是重复了DateAdd(day, (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
,这只是在计算当月的第一个星期四。
SELECT
FullDate,
CalendarYear,
IsFirstDayOfWeek,
CASE WHEN FullDate >= DateAdd(day, 28 + (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
THEN DateAdd(day, 28 + (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
WHEN FullDate >= DateAdd(day, 21 + (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
THEN DateAdd(day, 21 + (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
WHEN FullDate >= DateAdd(day, 14 + (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
THEN DateAdd(day, 14 + (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
WHEN FullDate >= DateAdd(day, 7 + (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
THEN DateAdd(day, 7 + (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
WHEN FullDate >= DateAdd(day, (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
THEN DateAdd(day, (12 - DatePart(DW, DateAdd(Month, DateDiff(Month, 0, FullDate),0)))%7, DateAdd(Month, DateDiff(Month, 0, FullDate),0))
ELSE FullDate - datepart(D,FullDate) + 1
END as [FirstDateOfWeekFullDate]
FROM YourDB..YourTable