Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server TSQL合并:目标表,其中“上”;关于;条件_Sql Server_Tsql_Merge - Fatal编程技术网

Sql server TSQL合并:目标表,其中“上”;关于;条件

Sql server TSQL合并:目标表,其中“上”;关于;条件,sql-server,tsql,merge,Sql Server,Tsql,Merge,我想使用merge,并且被来自有关ON连接条件的警告所吓倒: 仅指定目标表中包含的列非常重要 用于匹配目的。也就是说,从 目标表,该表与 源表。不要试图通过筛选来提高查询性能 在ON子句中输出目标表中的行,例如通过指定 而不是target_table.column_x=value。这样做可能会带来意想不到的后果 和错误的结果 下面是一个例子: -- drop table trg create table trg(department int not null,student int not nu

我想使用
merge
,并且被来自有关
ON
连接条件的警告所吓倒:

仅指定目标表中包含的列非常重要 用于匹配目的。也就是说,从 目标表,该表与 源表。不要试图通过筛选来提高查询性能 在ON子句中输出目标表中的行,例如通过指定 而不是target_table.column_x=value。这样做可能会带来意想不到的后果 和错误的结果

下面是一个例子:

-- drop table trg
create table trg(department int not null,student int not null,name nvarchar(20))
alter table trg add constraint PK_trg primary key clustered (department,student)
insert trg values (12,0,'Tony'),(12,1,'Helen'),(55,0,'Tony'),(55,1,'Helen')

-- drop table src 
go
create table src(student int not null,name nvarchar(20)) 
go
alter table src add constraint PK_src primary key clustered (student) 
go
insert src values (0,'Antony'),(1,'Helen'),(2,'Mike')

select * from trg
select * from src
训练表

+------------+---------+-------+
| department | student | name  |
+------------+---------+-------+
|         12 |       0 | Tony  |
|         12 |       1 | Helen |
|         55 |       0 | Tony  |
|         55 |       1 | Helen |
+------------+---------+-------+
两个系有2名学生(请忽略2nf违规,第三个系也应该依赖于该系,但我现在想不出一个例子)

现在,我们得到了一个
src
表,该表仅包含有关12部门的信息:

+---------+--------+
| student |  name  |
+---------+--------+
|       0 | Antony |
|       1 | Helen  |
|       2 | Mike   |
+---------+--------+
…我们想用
merge
src
中上传此信息

使用此选项:

merge trg using src on trg.student=src.student and trg.department=12
    when matched then update set name=src.name
    when not matched by target then insert values (12,src.student,src.name)
;
做我们想做的事。trg表现在具有所需的输出:

+------------+---------+--------+
| department | student |  name  |
+------------+---------+--------+
|         12 |       0 | Antony |
|         12 |       1 | Helen  |
|         12 |       2 | Mike   |
|         55 |       0 | Tony   |
|         55 |       1 | Helen  |
+------------+---------+--------+
我们可以看到,第12部门托尼的名字改成了安东尼,迈克被调到了第12部门,其他什么都没发生。这是通过违反参考警告来实现的。可以吗

我想它可以改写为:

merge trg using src on trg.student=src.student
    when matched and trg.department=12 then update set name=src.name
    when not matched by target then insert values (12,src.student,src.name);
这也确实是正确的


第一种反驳警告的方式是错误的,还是错误的做法?为什么?

发出警告的原因是,如果源表包含类似于
55,0,Tony
的内容,则这将被视为不匹配,并转到
插入
分支,这可能是意外的

但是,如果保证源表只包含部门12的项,那么这将按照您的需要工作

在这种情况下,还可以使用CTE之类的表表达式

WITH trg12
     AS (SELECT *
         FROM   trg
         WHERE  department = 12)
MERGE trg12 trg
using src
ON trg.student = src.student
WHEN matched THEN
  UPDATE SET name = src.name
WHEN NOT matched BY target THEN
  INSERT
  VALUES (12,
          src.student,
          src.name);
;

你好,请问。。。安东尼、海伦和迈克是12系的新生?如果是这样的话,问题不在于参考文献,因为你的关系是在“学生”栏中,也就是说。。。学生0=Tony->Mike,学生1=Helen->Helen,2=NULL->Mike(新行),因此,在合并条件中还将包括名称。。。欢迎汉克斯。这将是一个有用的参考。