繁体   English   中英

SQL Server:当另一列中的另一个数字大于 1 时,如何使用该列中的值更新列

[英]SQL Server: how to update a column with a value that is in that column when another number in another column is >1

我有一个包含以下数据的表:

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 

我不知道如何在非常大的数据集上实现这一点。 任何帮助将不胜感激!

换一种方式解释,部分级别
ABC 1
2
3
然后下一行填充另一部分 efg 1 2 2

等等。

进一步澄清:

我需要用字符串“abc”填充字符串“abc”,而下面的列字段为空。 下一行有一个 efg 字符串,下面的以下列字段为空,同样,这些字段应填充值“efg”,依此类推。

级别字段 = 1 将始终有一个部件号,但所有其他级别都报告到级别 1 部件,因此应以相同的方式填充。 并重复。

希望这是有道理的。

使用带有窗口函数的可更新 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 以查看发生了什么。

好吧,根据我的理解,您的问题是,您需要更新空列的值,直到获得非空值。 并且您想将其继续到表格的最后一行。 对于这种情况,我创建了一个存储过程,如果它为空,我会读取每个第 n 个单元格的值,然后用上一个更改它。 单元格的值,当单元格不为空时。

方法:

  1. 创建一个临时表/表变量。

  2. 添加一个额外的列,它基本上是标识,这将有助于对列进行排名。

  3. 迭代一个循环,直到达到最大行。

  4. 在每次迭代中,读取第 i 行的单元格值

    4.1 如果它不为空,则将其放入一个临时变量中。

    4.2 else,用临时变量替换/更新第i个单元格的值

  5. 继续它,直到到达表/表变量的最后一行。

看看我的以下片段:

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

您可以根据给定的场景使用临时表更新它我认为 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 

暂无
暂无

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

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