简体   繁体   English

SQL SERVER:每7行自动增加7

[英]SQL SERVER: auto-increment by 7 every 7 rows

I am trying to normalize a WeekOfYear column and my current format of the table looks somewhat like this: 我正在尝试规范WeekOfYear列,而我当前的表格格式如下所示:

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

How can I essentially pad in the missing values in the 'Week' column so it looks like this: 从本质上讲,我该如何填充“周”列中的缺失值,如下所示:

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

Here is a SQL query that creates a simple version of my problem's sample data: 这是一个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

My initial thoughts are to use some kind of built in auto-increment function, but if that does not exist then I would write some CASE statement that would say if the current row is blank, then use the number from the preceding row. 我最初的想法是使用某种内置的自动增量功能,但是如果该功能不存在,那么我会写一些CASE语句来说明当前行是否为空白,然后使用上一行的数字。

Any thoughts would be greatly appreciated. 任何想法将不胜感激。

Thanks in advance! 提前致谢!

SQL tables are inherently unordered. SQL表本质上是无序的。 So, with the sample data you provide, you cannot do what you want. 因此,使用您提供的样本数据,您将无法做自己想做的事情。

If you add a primary key to specify the ordering, then you can do what you want. 如果添加主键来指定顺序,则可以执行所需的操作。 This would look like: 看起来像:

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;

The rest of this assumes that the primary key is appropriately ordered but not necessarily gap-free. 其余部分假设主键已适当排序,但不一定无间隙。

You can then do what you want with simple arithmetic: 然后,您可以使用简单的算法执行所需的操作:

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

Alternatively, if you wanted to keep the current value, you can use the arithmetic to define groups and then "spread" the value in the group: 另外,如果您想保留当前值,则可以使用该算法定义组,然后在组中“传播”该值:

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;

EDIT: 编辑:

The above assumes that you have 7 items per group. 以上假设每个组有7个项目。 If this is not true, you can just count the valid value of wk : 如果不是这样,则可以只计算wk的有效值:

select max(wk) over (partition by grp) as newwk, f.*
from (select (count(wk) over (order by pk)) as grp, f.*
      from foobar f
     ) f;

Here is a SQL Fiddle. 是一个SQL Fiddle。

I assume you have some identity pk in your table to guarantee ordering: 我假设您的表中有一些身份pk以保证排序:

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

For update: 更新:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM