例如,日期是“2021-12-13”
所以我檢測該日期的周數: datepart(wk, '2021-12-13') --> 51
我需要找到去年那個 51 周的星期一和星期日的日期
uj5u.com熱心網友回復:
您可以從以下代碼段開始
with
original as (select '2021-12-23' as d),
lastyear as (
-- determine the same date last year
select dateadd(yy, -1, d) as d
from original
),
adjusted as (
-- since we do not want the same date, but the same calendar week,
-- we might need to add the difference between the two calendar weeks
select dateadd(
wk,
datepart(wk, original.d)-datepart(wk, lastyear.d),
lastyear.d) as d
from lastyear, original
)
select
-- finally determine the start and end of the week
dateadd(dd, 2 - datepart(dw, adjusted.d), adjusted.d) as "start",
dateadd(dd, 8 - datepart(dw, adjusted.d), adjusted.d) as "end",
from adjusted
但是,有幾點需要注意:
- 2 和 8 以及最后的 dateadd 是必需的,當您的 SQL 服務器在星期日開始一周時(即
datepart(dw, ...)星期一回傳 2)。最好在查詢中讀出服務器配置并使用適當的偏移量而不是對其進行硬編碼 - 該
adjustedCTE是處理與同日去年可能陷入另一壓延星期的事實非常明確的方式。肯定有更便宜的方法來實作這一點,但它們很可能看起來也更復雜,而且它們在做什么也不那么“明顯”。 - 我只玩了一點 SQL 小提琴,所以這真的需要測驗我可能錯過的極端情況。
- 一個極端情況是日歷第 53 周有時表示一年中的最后一周,有時表示第一周,有時可能同時表示兩者。我目前無法解決這個問題,因為我不知道你打算如何處理。
- ISO 周的正確日期部分是
isowk而不是wk. 您可能想使用它,但隨后您必須考慮如何使用它。由于Microsoft SQL不支持isowk的dateadd。
uj5u.com熱心網友回復:
周數和作業日數取決于 DATEFIRST 設定。
但是您可以使用@@datefirst 變數來更正計算,使其不受 DATEFIRST 設定的影響。
周一
dateadd(day, 1-(@@datefirst-1)-datepart(weekday, '2021-12-13'), '2021-12-13')
星期日
dateadd(day, 7-(@@datefirst-1)-datepart(weekday, '2021-12-13'), '2021-12-13')
測驗
set datefirst 1; select * , datepart(week, date_column) as week , datepart(weekday, date_column) as weekday , @@datefirst as df , datename(weekday, date_column) as weekday_name , [monday] = dateadd(day, 1-(@@datefirst-1)-datepart(weekday, date_column), date_column) , [sunday] = dateadd(day, 7-(@@datefirst-1)-datepart(weekday, date_column), date_column) from (values (cast('2021-12-13' as date)), ('2021-12-14'), ('2021-12-19') ) as val(date_column); GO
| 日期列 | 星期 | 作業日 | df | 作業日名稱 | 周一 | 星期日 |
|---|---|---|---|---|---|---|
| 2021-12-13 | 51 | 1 | 1 | 周一 | 2021-12-13 | 2021-12-19 |
| 2021-12-14 | 51 | 2 | 1 | 周二 | 2021-12-13 | 2021-12-19 |
| 2021-12-19 | 51 | 7 | 1 | 星期日 | 2021-12-13 | 2021-12-19 |
db<>在這里擺弄
或者您可以創建一個日歷表并進行查詢。
select cal_year, cal_df1_week
, min(cal_date) as begin_of_week
, max(cal_date) as end_of_week
from ref_calendar
where cal_year = datepart(year, '2021-12-14')
and cal_df1_week = datepart(week, '2021-12-14')
group by cal_year, cal_df1_week
日歷表的創建可以在這里找到
uj5u.com熱心網友回復:
請注意,因為給定年份中第 51 周的星期日和星期一不一定是連續的日期:
set datefirst 1;
select datepart(week, dt) as start_week, dt,
datename(weekday, candidate) as candidate_day,
datepart(week, candidate) as candidate_week,
candidate
from (values
(cast('2021-12-13' as date)), ('2020-12-13'), ('2019-12-13'),
('2018-12-13'), ('2017-12-13'), ('2016-12-13'),
('2015-12-13'), ('2014-12-13'), ('2013-12-13')
) as t(dt)
cross apply (values (-54), (-53), (-52), (-51), (-50)) as w(week_offset)
cross apply (values
(dateadd(week, week_offset, dateadd(day, -datepart(weekday, dt), dt)))) as v1(sunday)
cross apply (values (sunday), (dateadd(day, 1, sunday))) as v2(candidate)
where datepart(week, candidate) = 51
order by dt desc, candidate;
這個邏輯是在一個星期的范圍內向后搜索,然后尋找與第 51 周匹配的日期。你會看到事情發生了很多變化。我不確定這是你所期望的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/391763.html
