从复杂条件更新一个表

时间:2010-09-03 18:26:23

标签: sql sql-server sql-server-2005 tsql

提前感谢您的帮助。我正在为以下更新方案寻找一个简洁的解决方案:

  • 我有一个TableA,有5列(KeyCol,colA,ColB,ColC,ColD)
  • 我有另一个表2,有2列(KeyCol,AvgCol)

我想做这样的事情:

update AvgCol in table2, joining on KeyCol

从这个逻辑:

  • 如果colA和ColB都具有Non NUll值,则计算COlA和COlB的平均值并存储在tempA中,否则在TempA中选择coalesce(Cola / colb),如果两者都是nUll,则在TempA中为NULL
  • 如果colC和ColD都具有Non NUll值,则计算COlC和COl的平均值并存储在tempB中,否则在TempB中选择coalesce(ColC / colD),如果两者都是nUll,则在TempB中为NULL

  • 如果TempA和TempB都具有非NUll值,则计算TempA和TempB的平均值并存储在Table2.AvgCol中,否则选择coalesce(TempA / TempB),如果两者都是nUll,则为空

6 个答案:

答案 0 :(得分:1)

我认为这样做会。我正在使用isnull并交换每个isnull中列的顺序,因此如果该对中只有一列为null,则计算基本上变为(X + X)/ 2,它只是X.换句话说,如果只是其中一个为null,返回非null值。如果两者都为null,则整个计算将返回null。

;with cteTemp as (
    select keycol,
           (isnull(ColA, ColB) + isnull(ColB, ColA))/2 as TempA,
           (isnull(ColC, ColD) + isnull(ColD, ColC))/2 as TempB
        from TableA
)
update t2
    set AvgCol = (isnull(t1.TempA, t1.TempB) + isnull(t1.TempB, t1.TempA))/2
    from cteTemp t1
        inner join Table2 t2
            on t1.keycol = t2.keycol

答案 1 :(得分:1)

独占使用COALESCE可以大大减少代码开销:

UPDATE t2
SET AvgCol = COALESCE( (tempA + tempB) / 2, tempA, tempB)
FROM @table2 t2 
INNER JOIN (
  SELECT
    KeyCol, 
    COALESCE( (colA + colB) / 2, colA, colB) AS tempA,
    COALESCE( (colC + colD) / 2, colC, colD) AS tempB
  FROM @tableA
) tA ON t2.KeyCol = tA.KeyCol

答案 2 :(得分:0)

SELECT Table2.keycol AS KEY
       CASE
              WHEN colA   IS NULL
              AND    colb IS NULL
              THEN NULL
              WHEN colA   IS NOT NULL
              AND    colb IS NOT NULL
              THEN (colA + colB)/2
              ELSE COALESCE(colA,colB)
       END AS TempA,
       CASE
              WHEN colC   IS NULL
              AND    cold IS NULL
              THEN NULL
              WHEN colC   IS NOT NULL
              AND    cold IS NOT NULL
              THEN (colC + cold)/2
              ELSE COALESCE(colc,colc)
       END AS Tempb
FROM
ON (
              Table2.keycol = Table1.keycol
       )
UPDATE Table2
SET    AVG =
       CASE
              WHEN TempA   IS NULL
              AND    Tempb IS NULL
              THEN NULL
              WHEN TempA   IS NOT NULL
              AND    Tempb IS NOT NULL
              THEN (TempA + Tempb)/2
              ELSE COALESCE(TempA,Tempb)
       END
FROM
FROM   #temp innner
       JOIN Table2
       ON     Table2.keycol=#temp.key

答案 3 :(得分:0)

你应该使用案例

UPDATE TableB
SET AvgCol=
case when TempA is null and TempB is null then Null else 
case when TempA is not null and TempB is not null then (TempA+TempB)/2 else
coalesce(TempA, TempB) end  end 
FROM (select KeyCol,
    case when ColA is null and ColB is null then Null else 
    case when ColA is not null and ColB is not null then (ColA+ColB)/2 else
    coalesce(ColA, ColB) end  end as TempA,
    case when ColC is null and ColD is null then Null else 
    case when ColC is not null and ColD is not null then (ColC+ColD)/2 else
    coalesce(ColC, ColD) end  end as TempB
    FROM TableA) TEMP
INNER JOIN TableB
on TEMP.KeyCol=TableB.KeyCol

答案 4 :(得分:0)

试试这个尺寸

update Table2
set AvgCol= case when TempA+TempB is null then coalesce(TempA,TempB) else (TempA+TempB)/2 end
from
    Table2 b
        inner join 
(
    select
        case when ColA+ColB is null then coalesce(ColA,ColB) else (ColA+ColB)/2 end as TempA,
        case when ColC+ColD is null then coalesce(ColC,ColD) else (ColC+ColD)/2 end as TempB,
        a.KeyCol
    from TableA a
        inner join Table2 b
            on a.KeyCol=b.KeyCol
) a
    on B.KeyCol=a.KeyCol

将数字添加到null时,结果为null。 coalesce,如果两个值都为null,则返回null。

答案 5 :(得分:0)

只是为了好玩,这里已经有足够的其他解决方案了:

declare @TempA float, @TempB float

update b set 
  @TempA = coalesce((a.ColA+a.ColB)/2, a.ColA, a.ColB)
, @TempB = coalesce((a.ColC+a.ColD)/2, a.ColC, a.ColD)
, AvgCol = coalesce((@TempA+@TempB)/2, @TempA, @TempB)
from TableA a
join Table2 b on a.KeyCol = b.KeyCol