2016-10-28 30 views
0

我有一个日历星期列表中的SQL结构如下确定时间,没有前任

|SPECIAL_PERIOD| 
201543 
201601 
201614 
201615 
201622 

我想要做的就是找回星期里立即在特殊时期之前的名单 - 但间没有” T特殊:

|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

的SQL Server版本? – MtwStark

回答

0

如果你不想在where子句中再次使用该列表中,您可以重命名PREVIOUS_WEEKS如在SQL语句相同列表的另一个副本特殊星期,做自然连接。这将只给出两者之间的通用条目。这在概念上与使用WHERE子句相同。

我认为年休息可以通过在声明中使用数字比较来管理,而不是数字的字符串级别比较。

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 
相关问题