我需要进行此更新,以便为一系列存储桶添加另一个值(B1-B5),但只有一次进入第一个存储区,如下面的示例所示,一旦填充就无法提供任何解决方案来标记它,试图使用旗帜,但看起来它并没有'在相同的tx期间工作。这是示例代码,但尚未正确。我是MSQL 2016。 谢谢大家的评论;
/*
SELECT * INTO #t FROM (
SELECT 101 CustID, 100 B1, 200 B2 , NULL B3, NULL B4, NULL B5, '0' [f], 111 NewB , 'B4,B5 sbe empty' Note UNION
SELECT 102 CustID, 100 B1, 200 B2 , 300 B3, NULL B4, NULL B5, '0' [f], 222 NewB , '22 goes only into B4, B5 empty' Note UNION
SELECT 103 CustID, 100 B1, 200 B2 , 300 B3, 400 B4 , NULL B5, '0' [f], 333 NewB , '333 goes into B5' Note )x */
-- SELECT * FROM #t -- before DROP TABLE #t
-- how to Put NewB only ONCE into first empty B1-5
update #t
SET B1 = CASE WHEN B1 IS NULL THEN NewB ELSE B1 END,
B2 = CASE WHEN B2 IS NULL THEN NewB ELSE B2 END,
B3 = CASE WHEN B3 IS NULL THEN NewB ELSE B3 END,
B4 = CASE WHEN B4 IS NULL THEN NewB ELSE B4 END,
B5 = CASE WHEN B5 IS NULL THEN NewB ELSE B5 END
SELECT * FROM #t
----------------------
CustID B1 B2 B3 B4 B5 _ NewB Note
101 100 200 111 111 111 - 111 B4,B5 sbe empty
102 100 200 300 222 222 - 222 B5 sbe empty
103 100 200 300 400 333 - 333 333 goes into B5
** tried : f = CASE WHEN B1 IS NULL THEN 1 ELSE 0 END ,
A column cannot be assigned more than one value in the same clause
答案 0 :(得分:1)
测试所有先前的值是否为空,即尚未设置。
update #t
SET B1 = CASE WHEN B1 IS NULL THEN NewB ELSE B1 END,
B2 = CASE WHEN B2 IS NULL AND
B1 IS NOT NULL THEN NewB ELSE B2 END,
B3 = CASE WHEN B3 IS NULL AND
B1 IS NOT NULL AND B2 IS NOT NULL THEN NewB ELSE B3 END,
B4 = CASE WHEN B4 IS NULL AND
B1 IS NOT NULL AND B2 IS NOT NULL AND B3 IS NOT NULL THEN NewB ELSE B4 END,
B5 = CASE WHEN B5 IS NULL AND
B1 IS NOT NULL AND B2 IS NOT NULL AND B3 IS NOT NULL AND B4 IS NOT NULL
THEN NewB ELSE B5 END
SELECT * FROM #t
另请参阅:Importance of Column Order in the SET Clause in Update Statements
答案 1 :(得分:1)
您应该检查前面所有列的值:
update #t
SET B1 = CASE WHEN B1 IS NULL THEN NewB ELSE B1 END,
B2 = CASE WHEN B1 IS NULL AND B2 IS NULL THEN NewB ELSE B2 END,
B3 = CASE WHEN B1 IS NULL AND B2 IS NULL AND B3 IS NULL THEN NewB ELSE B3 END,
B4 = CASE WHEN B1 IS NULL AND B2 IS NULL AND B3 IS NULL AND B4 IS NULL THEN NewB ELSE B4 END,
B5 = CASE WHEN B1 IS NULL AND B2 IS NULL AND B3 IS NULL AND B4 IS NULL AND B5 IS NULL THEN NewB ELSE B5 END
或者,您可以使用单独的更新语句,但在影响该行的第一个UPDATE中删除NewB的值:
ALTER TABLE #t ALTER COLUMN NewB INT NULL
update #t SET B1 = NewB, NewB=NULL WHERE B1 IS NULL AND NewB IS NOT NULL
update #t SET B2 = NewB, NewB=NULL WHERE B2 IS NULL AND NewB IS NOT NULL
update #t SET B3 = NewB, NewB=NULL WHERE B3 IS NULL AND NewB IS NOT NULL
update #t SET B4 = NewB, NewB=NULL WHERE B4 IS NULL AND NewB IS NOT NULL
update #t SET B5 = NewB, NewB=NULL WHERE B5 IS NULL AND NewB IS NOT NULL
答案 2 :(得分:1)
您可以使用CROSS APPLY
创建一个引用字段,指示应更新哪个列。在下面的代码中,如果需要,IIF
可以替换为CASE
表达式。
UPDATE t
SET B1 = IIF(NextBucket = 'B1', NewB, B1)
, B2 = IIF(NextBucket = 'B2', NewB, B2)
, B3 = IIF(NextBucket = 'B3', NewB, B3)
, B4 = IIF(NextBucket = 'B4', NewB, B4)
, B5 = IIF(NextBucket = 'B5', NewB, B5)
FROM #t t
CROSS APPLY (SELECT NextBucket = CASE
WHEN B1 IS NULL THEN 'B1'
WHEN B2 IS NULL THEN 'B2'
WHEN B3 IS NULL THEN 'B3'
WHEN B4 IS NULL THEN 'B4'
WHEN B5 IS NULL THEN 'B5'
END) nb;
答案 3 :(得分:1)
update #t
SET
b1 = coalesce( b1, newb),
b2 = case when b1 is not null then coalesce(b2, newb) else b2 end,
b3 = case when b1 is not null and b2 is not null then coalesce(b3, newb) else b3 end,
b4 = case when b1 is not null and b2 is not null and b3 is not null then coalesce(b4, newb) else b4 end,
b5 = case when b1 is not null and b2 is not null and b3 is not null and b4 is not null then coalesce(b5, newb) else b5 end