确定没有前任的时期

时间:2016-10-28 07:27:47

标签: sql select

我在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)?

2 个答案:

答案 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子句相同。

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