SQL 服务器:当另一列中的另一个数字大于 1 时,如何使用该列中的值更新该列
SQL Server: how to update a column with a value that is in that column when another number in another column is >1
我有一个 table,其中包含以下数据:
Part Comp level item_nbr
-------------------------------
abc ab 1 1
null cd 2 2
null ef 3 3
cde gh 1 4
null ij 2 5
null kl 3 6
null mn 4 7
我想将空值更新为每个级别 1 中的值,因此每个 >1 的级别都用级别一的值更新。
Part Comp level
---------------------
abc ab 1
abc cd 2
abc ef 3
cde gh 1
cde ij 2
cde kl 3
cde mn 4
我不知道如何在非常大的数据集上实现这一点。任何帮助将不胜感激!
换个方式解释,
部分级别
美国广播公司 1
2
3
然后下一行填充另一部分
效果图 1
2个
2
等等
进一步说明:
我需要用字符串 "abc" 填充字符串 "abc",而下面的列字段为空。下一行有一个 efg 字符串,下面的以下列字段为空,同样,这些字段应该用值 "efg" 填充,依此类推。
级别字段 = 1 将始终有一个零件号,但所有其他级别报告到级别 1 零件,因此应该以相同方式填充。并重复。
希望这是有道理的。
好吧,根据你的问题我的理解是,你需要更新空列的值,直到你得到一个非空值。并且您想继续到 table 的最后一行。
对于这种情况,我创建了一个存储过程,我在其中读取每个第 n 个单元格的值(如果它为 null)我用 prev 更改它。单元格的值,当单元格不为空时。
方法:
创建临时 table/table 变量。
添加一个额外的列,基本上是标识,这将有助于对列进行排名。
重复一个循环,直到达到最大行数。
在每次迭代中,读取第 i 行的单元格值
4.1 如果不为null 就放在一个临时变量中。
4.2 else, replace/update 第 i 个单元格的临时变量值
继续,直到到达 table/table 变量的最后一行。
看看我的以下片段:
create proc DemoPost
as
begin
declare @table table(serial_no int identity(1,1), name varchar(30), text varchar(30), level int)
insert @table
select Name, Text, Level from Demo
declare @max as int = (select max(serial_no) from @table)
--select @max
declare @i as int =0
declare @temp as varchar(30)
declare @text as varchar(30)
while @i < @max
begin
set @i = @i +1
set @temp = (select name from @table where serial_no = @i)
-- if @temp is not null, fetch its value, otherwise, update/replace it with
-- previously gotten not-null cell's value.
if @temp is not null
begin
set @text = (select name from @table where serial_no = @i)
end
else
begin
update @table
set name = @text where serial_no = @i
end
end
select name, text, level from @table
end
您可以根据给定的场景使用临时 table 更新它 我认为 item_nbr 在行中是独一无二的 希望这会有所帮助
SELECT *
INTO #TEMP
FROM URTablehere
DECLARE @PRev VARCHAR(MAX)
WHILE ( SELECT COUNT(*)
FROM URTablehere
) > 0
BEGIN
DECLARE @ID INT
DECLARE @Part VARCHAR(MAX)
DECLARE @Num INT
SELECT TOP ( 1 )
@ID = level ,
@Part = Part ,
@Num = item_nbr
FROM #TEMP
IF ( @ID = 1 )
BEGIN
SELECT @PRev = @Part
END
IF ( @ID > 1
AND @Part IS NULL
)
BEGIN
UPDATE URTablehere
SET Part = @PRev
WHERE item_nbr = @Num
END
DELETE
FROM #TEMP WHERE item_nbr=@Num
END
使用具有 window 功能的可更新 CTE:
with toupdate as (
select t.*,
max(part) over (partition by itm_nbr_not_null) as new_part
from (select t.*,
max(case when part is not null then item_nbr end) over (order by item_nbr) as itm_nbr_not_null
from t
) t
)
update toupdate
set part = new_part
where part is null;
您可以 运行 CTE 看看发生了什么。
我有一个 table,其中包含以下数据:
Part Comp level item_nbr
-------------------------------
abc ab 1 1
null cd 2 2
null ef 3 3
cde gh 1 4
null ij 2 5
null kl 3 6
null mn 4 7
我想将空值更新为每个级别 1 中的值,因此每个 >1 的级别都用级别一的值更新。
Part Comp level
---------------------
abc ab 1
abc cd 2
abc ef 3
cde gh 1
cde ij 2
cde kl 3
cde mn 4
我不知道如何在非常大的数据集上实现这一点。任何帮助将不胜感激!
换个方式解释,
部分级别
美国广播公司 1
2
3
然后下一行填充另一部分
效果图 1
2个
2
等等
进一步说明:
我需要用字符串 "abc" 填充字符串 "abc",而下面的列字段为空。下一行有一个 efg 字符串,下面的以下列字段为空,同样,这些字段应该用值 "efg" 填充,依此类推。
级别字段 = 1 将始终有一个零件号,但所有其他级别报告到级别 1 零件,因此应该以相同方式填充。并重复。
希望这是有道理的。
好吧,根据你的问题我的理解是,你需要更新空列的值,直到你得到一个非空值。并且您想继续到 table 的最后一行。 对于这种情况,我创建了一个存储过程,我在其中读取每个第 n 个单元格的值(如果它为 null)我用 prev 更改它。单元格的值,当单元格不为空时。
方法:
创建临时 table/table 变量。
添加一个额外的列,基本上是标识,这将有助于对列进行排名。
重复一个循环,直到达到最大行数。
在每次迭代中,读取第 i 行的单元格值
4.1 如果不为null 就放在一个临时变量中。
4.2 else, replace/update 第 i 个单元格的临时变量值
继续,直到到达 table/table 变量的最后一行。
看看我的以下片段:
create proc DemoPost
as
begin
declare @table table(serial_no int identity(1,1), name varchar(30), text varchar(30), level int)
insert @table
select Name, Text, Level from Demo
declare @max as int = (select max(serial_no) from @table)
--select @max
declare @i as int =0
declare @temp as varchar(30)
declare @text as varchar(30)
while @i < @max
begin
set @i = @i +1
set @temp = (select name from @table where serial_no = @i)
-- if @temp is not null, fetch its value, otherwise, update/replace it with
-- previously gotten not-null cell's value.
if @temp is not null
begin
set @text = (select name from @table where serial_no = @i)
end
else
begin
update @table
set name = @text where serial_no = @i
end
end
select name, text, level from @table
end
您可以根据给定的场景使用临时 table 更新它 我认为 item_nbr 在行中是独一无二的 希望这会有所帮助
SELECT *
INTO #TEMP
FROM URTablehere
DECLARE @PRev VARCHAR(MAX)
WHILE ( SELECT COUNT(*)
FROM URTablehere
) > 0
BEGIN
DECLARE @ID INT
DECLARE @Part VARCHAR(MAX)
DECLARE @Num INT
SELECT TOP ( 1 )
@ID = level ,
@Part = Part ,
@Num = item_nbr
FROM #TEMP
IF ( @ID = 1 )
BEGIN
SELECT @PRev = @Part
END
IF ( @ID > 1
AND @Part IS NULL
)
BEGIN
UPDATE URTablehere
SET Part = @PRev
WHERE item_nbr = @Num
END
DELETE
FROM #TEMP WHERE item_nbr=@Num
END
使用具有 window 功能的可更新 CTE:
with toupdate as (
select t.*,
max(part) over (partition by itm_nbr_not_null) as new_part
from (select t.*,
max(case when part is not null then item_nbr end) over (order by item_nbr) as itm_nbr_not_null
from t
) t
)
update toupdate
set part = new_part
where part is null;
您可以 运行 CTE 看看发生了什么。