我在SQL中有一个具有以下结构的日历周列表
|SPECIAL_PERIOD|
201543
201601
201614
201615
201622
我想要做的是检索特殊时期之前的周列表 - 但并不特别:
|PREVIOUS_WEEKS|
201542
201553
201613
201614 --> This one is special, so don't display
201621
即。我的最终名单应如下:
|PREVIOUS_WEEKS_CLEAN|
201542
201553
201613
201621
现在我有两个问题:
如何检查" previous_week"首先是特殊的(希望没有再次检索初始列表并在where子句中使用它)?
如何管理年度休息(即201601的前一周不是201601-1而是201553)?
答案 0 :(得分:2)
从sql server 2012你可以使用LAG()函数:
;with
d as (
select SPECIAL_PERIOD, dateadd(WEEK, cast(right(SPECIAL_PERIOD, 2) as int)-1, DATEFROMPARTS(cast(left(SPECIAL_PERIOD, 4) as int), 1, 1)) wk
from MyCalendar
),
p as (
select d.*, LAG(wk) over (order by SPECIAL_PERIOD) prev, dateadd(week, -1, wk) prev_wk
from d
)
select *, iif(prev=prev_wk,1,0) is_special
from p
where prev<>prev_wk -- rem this to see special weeks
order by 1
对于sql server 2008,您可以使用以下语法:
;with
d as (
select ROW_NUMBER() over (order by SPECIAL_PERIOD) N, SPECIAL_PERIOD, dateadd(WEEK, cast(right(SPECIAL_PERIOD, 2) as int)-1, DATEFROMPARTS(cast(left(SPECIAL_PERIOD, 4) as int), 1, 1)) wk
from #cal
),
p as (
SELECT d.*,p.wk prev, dateadd(week, -1, d.wk) prev_wk
FROM D
LEFT JOIN D p on d.N = p.n+1
)
select *, case when prev=prev_wk then 1 else 0 end is_special
from p
where prev<>prev_wk -- rem this to see special weeks
order by 1
答案 1 :(得分:0)
如果您不想在where子句中再次使用该列表,则可以将PREVIOUS_WEEKS重命名为SQL语句中同一列表的另一个副本的SPECIAL WEEKS并执行自然连接。这将只给出两者之间的公共条目。这在概念上与使用WHERE子句相同。
我认为可以通过在语句中使用数字比较来管理年度休息,而不是数字的字符串级别比较。