1

我正在尝试解决 t-sql 练习我需要通过 id 加入来使用第二个值更新第一个表。如果我无法加入,则使用默认 ID 中的值(默认 ID 是为空的 ID)

请运行它以查看它

declare @t as table (
    [id] INT
    ,val int
)

insert into @t values (null, null)
insert into @t values (2, null)
insert into @t values (3, null)
insert into @t values (4, null)

declare @t2 as table (
    [id] INT
    ,val int
)

insert into @t2 values (null, 11)
insert into @t2 values (2, 22)
insert into @t2 values (3, 33)


select * from @t
select * from @t2

update t
set t.val = t2.val
from @t as t join @t2 as t2
    on t.id = t2.id
        or 
        (
            (t.id is null or t.id not in (select id from @t2))
            and t2.id is null
        )




select * from @t

这是结果

--@t
id      val
---------------
NULL    NULL
2       NULL
3       NULL
4       NULL

--@t2
id      val
---------------
NULL    11
2       22
3       33

--@t after update
id      val
---------------
NULL    11
2       22
3       33
4       NULL

如何使最后一行的 val 等于 11?

4       11
4

3 回答 3

3

此解决方案左连接到 t2 两次,然后进行合并。

第二ON个连接上的 匹配连接失败的记录,然后查找“默认”情况。

UPDATE t
set t.val = COALESCE(t2.val,t3.val)
from @t as t 
    LEFT join @t2 as t2
    on t.id = t2.id
    LEFT JOIN @t2 t3 
    ON t2.id is null and t3.id is null

看到它在这里工作

于 2012-04-16T21:32:47.773 回答
2

试试这个更新...

update t
set t.val = t2.val
from @t as t join @t2 as t2
    on t.id = t2.id
        or 
        (
            (t.id is null or not exists (select * from @t2 where id = t.id))
            and t2.id is null
        )

问题在于not in运算符和null值。这也可以工作......

update t
set t.val = t2.val
from @t as t join @t2 as t2
    on t.id = t2.id
        or 
        (
            (t.id is null or t.id not in (select id from @t2 where id is not null))
            and t2.id is null
        )
于 2012-04-16T21:33:56.503 回答
1

这是一种可能会有所帮助的技术。

从您想要编写的简单代码开始:

MERGE INTO @t AS target 
   USING source 
      ON target.id = source.id 
WHEN MATCHED THEN
   UPDATE 
      SET val = source.val;

source然后写一个满足要求的表表达式( )。

要求1:“通过id加入”

-- 简单的存在量化,例如

SELECT id, val
  FROM @t2 AS T2
 WHERE id IN ( SELECT id FROM @t ) 

要求 2:“如果我不能加入,则使用默认 ID 中的值(默认 iD 是为空的 ID)”

-- 首先id在目标中找到源中不存在的值:

SELECT id
  FROM @t
EXCEPT
SELECT id
  FROM @t2

然后将结果与 Id 为空的源中的行交叉连接:

SELECT DT1.id, T2.val
  FROM ( SELECT id
          FROM @t
         EXCEPT
         SELECT id
          FROM @t2 ) AS DT1, 
       @t2 AS T2 
 WHERE T2.id IS NULL

此时,您将需要查询一些测试数据以确保每个查询都满足其各自的要求。

将上述两个结果联合起来形成一个表表达式:

SELECT id, val
  FROM @t2 AS T2
 WHERE id IN ( SELECT id
                 FROM @t )             
UNION
SELECT DT1.id, T2.val
  FROM ( SELECT id
          FROM @t
         EXCEPT
         SELECT id
          FROM @t2 ) AS DT1, 
       @t2 AS T2 
 WHERE T2.id IS NULL

然后将表表达式插入MERGE样板代码:

WITH source
     AS
     (
      SELECT id, val
        FROM @t2 AS T2
       WHERE id IN ( SELECT id
                       FROM @t )             
      UNION
      SELECT DT1.id, T2.val
        FROM ( SELECT id
                FROM @t
               EXCEPT
               SELECT id
                FROM @t2 ) AS DT1, 
             @t2 AS T2 
       WHERE T2.id IS NULL
     )
MERGE INTO @t AS target 
   USING source 
      ON target.id = source.id 
WHEN MATCHED THEN
   UPDATE 
      SET val = source.val;
于 2012-04-17T12:23:40.490 回答