给出:
主表:
let str = 'hi i am jack'
str = arr.split(' ').map(word => `${word[0].toUpperCase()}${word.slice(1)}`).join(' ');
console.log(str) // 'Hi I Am Jack'
新行表:
A B C
a1 b1 NULL
a3 b2 NULL
所需的输出:
A B C
a1 b1 c1
a2 b2 c2
我需要一个查询,用于比较主表和New_Row表之间的每一列,如果该行中的所有其他列都相同,则更新主表行,或者如果该行中的其他列不同,则插入新行。
在上面的示例中,New_Row表中的第一行与主表中的第一行匹配,但NULL值除外(假定主表缺少此数据),因此在所需的输出中填充了c1。 New_Row表中的第二行与主表中的任何行都不匹配(因为主表中没有a3 b2行),因此它将作为新行插入到所需的输出中。
我将如何编写此查询?
答案 0 :(得分:2)
SQL Server支持MERGE
语句以在单个查询中执行INSERT
,UPDATE
或DELETE
操作。
您可以在这里找到有关此声明的详细信息:https://docs.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql
MERGE [master_table] AS TARGET
USING [new_row_table] AS SOURCE
ON (TARGET.A = SOURCE.A) AND (TARGET.B = SOURCE.B)
WHEN MATCHED THEN
UPDATE SET TARGET.C = SOURCE.C
WHEN NOT MATCHED BY TARGET THEN
INSERT (A, B, C)
VALUES (SOURCE.A, SOURCE.B, SOURCE.C);
一个警告-MERGE
仅在SQL Server 2008及更高版本中受支持。
答案 1 :(得分:2)
因此,在两个表中都没有唯一键的情况下,这有点麻烦,但仍然可行。您可以使用MERGE
语句或显式事务来执行此操作。您使用哪一个主要取决于您。就我个人而言,我不是MERGE
的忠实拥护者,因为我发现语法很笨拙,并且可能会有一些奇怪的行为,但这取决于您。另外,我不确定表上是否存在任何唯一约束,但是如果没有,并且有可能重复,那么您可能要避免使用MERGE
,因为它在更新非约束时效果不佳-独特的数据集。
无论采用哪种方法,您还需要注意如何处理NULL
值。如果您只是进行直接比较(例如t.c = s.c
),而其中一列为空,则将从不评估为true(因为null
从不等于任何东西;甚至另一个null
)。如果您很在意这一点,则需要用占位符值替换空值(例如isnull(t.c, '') = isnull(s.c, '')
,或者另外检查列是否为空值(例如(t.c is null or s.c is null or t.c = s.c)
设置数据
if object_id('tempdb.dbo.#New') is not null drop table #Master
create table #Master
(
a varchar(10),
b varchar(10),
c varchar(10)
)
if object_id('tempdb.dbo.#new') is not null drop table #new
create table #new
(
a varchar(10),
b varchar(10),
c varchar(10)
)
insert into #master
values ('a1', 'b1', null), ('a2', 'b2', null)
insert into #new
values ('a1', 'b1', 'c1'), ('a2', 'b2', 'c2')
方法1:合并
merge into #master t -- target
using #new s --source
on t.a = s.a
and t.b = s.b
and t.c = s.c
when not matched by target then insert
(
a,
b,
c
)
values
(
s.a,
s.b,
s.c
)
when matched then update
set c = s.c;
方法2:明确交易
begin tran
update t
set c = s.c
from #master t -- target
inner join #new s -- source
on t.a = s.a
and t.b = s.b
and t.c = s.c
insert into #master
(
a,
b,
c
)
select
s.a,
s.b,
s.c
from #new s -- source
left outer join #master t --target
on s.a = t.a
and s.b = t.b
and s.c = t.c
where t.a is null
commit tran