SQL SERVER:每7行自动递增7

时间:2015-07-06 22:40:25

标签: sql sql-server

我正在尝试规范化WeekOfYear列,我当前的表格格式看起来像这样:

Week  DOW
  1  FRIDAY
     SATURDAY
     SUNDAY
     MONDAY
     TUESDAY
     ...
  2  FRIDAY
     SATURDAY
     SUNDAY
     MONDAY
     TUESDAY
     ...

如何在“周”中填写缺失值?列,所以它看起来像这样:

Week  DOW
  1  FRIDAY
  1  SATURDAY
  1  SUNDAY
  1   MONDAY
  1  TUESDAY
  1  ...
  2  FRIDAY
  2  SATURDAY
  2  SUNDAY
  2  MONDAY
  2  TUESDAY
  2  ...

这是一个SQL查询,它创建了我的问题的示例数据的简单版本:

CREATE TABLE dbo.foobar
(
 Wk CHAR(2),
 DOW CHAR(10)
 );


 INSERT INTO dbo.foobar(Wk, DOW)
 VALUES 
 (1, 'FRIDAY'),
 (NULL,'SATURDAY'),
 (NULL,'SUNDAY'),
 (2, 'FRIDAY'),
 (NULL,'SATURDAY'),
 (NULL,'SUNDAY')


 SELECT * FROM dbo.foobar

我最初的想法是使用某种内置的自动递增功能,但如果不存在那么我会写一些CASE语句,如果当前行是空白,则使用前一行中的数字

任何想法都会非常感激。

提前致谢!

2 个答案:

答案 0 :(得分:2)

SQL表本质上是无序的。因此,使用您提供的示例数据,您无法做您想做的事。

如果添加主键以指定排序,则可以执行所需操作。这看起来像是:

ORDER BY

其余部分假定主键是有序,但不一定是无间隙的。

然后你可以用简单的算法做你想做的事情:

CREATE TABLE dbo.foobar (
    pk int not null identity(1, 1) primary key,
    Wk CHAR(2),
    DOW CHAR(10)
 );


INSERT INTO dbo.foobar(Wk, DOW)
  VALUES (1, 'FRIDAY'),
         (NULL,'SATURDAY'),
         (NULL,'SUNDAY'),
         (2, 'FRIDAY'),
         (NULL,'SATURDAY'),
         (NULL,'SUNDAY');

 SELECT * FROM dbo.foobar;

或者,如果您想保留当前值,可以使用算术来定义组,然后" spread"组中的值:

select 1 + (row_number() over (order by pk) - 1) / 7 as newwk, f.*
from foobar;

编辑:

以上假设您每组有7个项目。如果不是这样,您只需计算select max(wk) over (partition by grp) as newwk, f.* from (select 1 + (row_number() over (order by pk) - 1) / 7 as grp, f.* from foobar f ) f; 的有效值:

wk

Here是一个SQL小提琴。

答案 1 :(得分:1)

我假设你的桌子上有一些身份证明,以保证订购:

select wk as oldwk, 
       dow, 
       (select top 1 wk 
        from foobar f2 
        where f2.id <= f1.id and f2.wk is not null
        order by f2.id desc) as newwk
from foobar f1

更新:

update f1
set wk = (select top 1 wk 
          from foobar f2 
          where f2.id <= f1.id and f2.wk is not null
          order by f2.id desc)
from foobar f1