在SQL Server中,我有一个如下所示的表。它有147行(列1(。第4列有9个不同的值。现在我需要重复第4列的结果集,直到它达到最后一个记录147。我已经粘贴在输出查询下面。请提供建议。
Lookup Col2 col3 col4
--------------------------------
1 14967081 10 1351327
2 14967082 20 1351328
3 14967083 30 1351329
4 14969084 45 1351330
5 14969085 52 1351331
6 14969086 67 1351332
7 14969087 79 1351333
8 14969088 81 1351334
9 14969089 97 1351335
10 14969090 10 NULL
11 14969091 11 NULL
12 14969092 12 NULL
13 14969093 13 NULL
14 14969094 14 NULL
15 14969095 15 NULL
.. ... .. NULL
.. ...
147 14969118 190 NULL
所需输出应如下所示:
Lookup Col2 col3 col4
---------------------------------
1 14967081 10 1351327
2 14967082 20 1351328
3 14967083 30 1351329
4 14969084 45 1351330
5 14969085 52 1351331
6 14969086 67 1351332
7 14969087 79 1351333
8 14969088 81 1351334
9 14969089 97 1351335
10 14969090 10 1351327
11 14969091 11 1351328
12 14969092 12 1351329
13 14969093 13 1351330
14 14969094 14 1351331
15 14969095 15 1351332
.. ... .. 1351333
.. ... .. 1351334
.. ... .. 1351335
.. ... .. 1351327
.. ... .. 1351328
.. ... .. ......
147 14969118 190 1351327
如果查找真的是连续的,没有间隙,你可以使用模运算和窗口函数:
select t.*,
max(col4) over (partition by lookup % 9) as imputed_col4
from t;
如果你不能依靠lookup
来实现无间隙,那么你也可以使用row_number()
:
select t.*,
max(col4) over (partition by seqnum % 9) as imputed_col4
from (select t.*, row_number() over (order by lookup) as seqnum
from t
) t
order by lookup;
这两者也可以合并到update
语句中。例如:
with toupdate as (
select t.*,
max(col4) over (partition by lookup % 9) as imputed_col4
from t
)
update toupdate
set col4 = imputed_col4
where col4 is null;
这里有一个db<gt;不停摆弄
您可以使用提醒运算符并映射如下所示的值:
declare @table table(Looku int, Col2 int, col3 int, col4 int)
insert into @table
values
(1 ,14967081 ,10 ,1351327)
,(2 ,14967082 ,20 ,1351328)
,(3 ,14967083 ,30 ,1351329)
,(4 ,14969084 ,45 ,1351330)
,(5 ,14969085 ,52 ,1351331)
,(6 ,14969086 ,67 ,1351332)
,(7 ,14969087 ,79 ,1351333)
,(8 ,14969088 ,81 ,1351334)
,(9 ,14969089 ,97 ,1351335)
,(10 ,14969090 ,10 ,NULL )
,(11 ,14969091 ,11 ,NULL )
,(12 ,14969092 ,12 ,NULL )
,(13 ,14969093 ,13 ,NULL )
,(14 ,14969094 ,14 ,NULL )
,(15 ,14969095 ,15 ,NULL )
SELECT t.looku, t.Col2, t.col3, ISNULL(t.col4, c.col4)
FROM @table as t
LEFT OUTER JOIN
(
select t1.looku , t1.col4
FROM @table AS T1
WHERE T1.Looku <= 9 ) as c
ON iif(t.Looku % 9 = 0,9,t.Looku % 9) = c.looku
looku | 第2列 | 第3列 | 第4列||
---|---|---|---|---|
1 | 14967081 | 10 | 1351327 | |
2 | 14967082 | 20 | 1351328 | |
3 | 14967083 | 30 | 1351329 | |
4 | 14969084 | 45 | <1351330>||
5 | 14960985 | 52 | 1351331 | |
6 | 14969086 | 67 | 1351332 | |
7 | 14969087 | 79 | 1351333 | |
8 | 14969088 | 81 | 1351334 | |
9 | 14969089 | 97 | 1351335 | |
10 | 14969090 | <10>1351327 | ||
11 | 14969091 | <11>1351328 | ||
12 | 14969092 | <12>1351329 | ||
13 | 14969093 | <13>1351330 | ||
14 | 14969094 | 14 | 1351331 | |
15 | 14969095 | 15 | 1351332 |
您需要根据所拥有的不同值计算一个行号,在整个表上计算一个行数,然后用模计算将两者连接起来
SELECT
t.Lookup,
t.Col2
t.col3
ISNULL(t.col4, DistinctValues.col4)
FROM (
SELECT *,
rn = ROW_NUMBER() OVER (PARTITION BY CASE WHEN col4 IS NULL THEN 1 ELSE 0 END
ORDER BY Lookup) - 1
FROM table
) t
LEFT JOIN (
SELECT col4,
rn = ROW_NUMBER() OVER (ORDER BY MIN(Lookup)) - 1,
cnt = COUNT(*) OVER ()
FROM table
WHERE col4 IS NOT NULL
GROUP BY col4
) DistinctValues
ON DistinctValues.rn = t.rn % DistinctValues.cnt AND t.col4 IS NULL
我的想法是嵌套的。使用值1351327更新col4,并在每个循环上递增。当更新第9次时,将值重置回1351327,并在id未重置时再次递增。我写了这样的查询:
declare @val int = 1351327, @rows int = 0, @inc int = 0, @id int = 1
while @rows < 147
begin
while @inc < 9
begin
update tbl
set col4 = @val
where lookup = @id
set @rows= @rows + 1
set @val = @val + 1
set @inc= @inc + 1
set @id = @id + 1
end
set @inc = 0
set @val = 1351327
end
检查db fiddle的输出。