我正在尝试规范化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语句,如果当前行是空白,则使用前一行中的数字
任何想法都会非常感激。
提前致谢!
答案 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