sql - 使用连接重复项更新语句

标签 sql sql-server

当使用 INNER JOIN 执行更新导致目标表中的记录重复时,关于将结果表中的哪些行作为要应用于更新的记录的规则是什么?

例如:

T1:

|-------------|-------------|
|     col1    |     col2    |
|-------------|-------------|
|       1     |       A     |
|-------------|-------------|
|       1     |       B     |
|-------------|-------------|
|       1     |       C     |
|-------------|-------------|

T2:

|-------------|-------------|
|     col1    |     col2    |
|-------------|-------------|
|       1     |       D     |
|-------------|-------------|
|       1     |       E     |
|-------------|-------------|
|       1     |       F     |
|-------------|-------------|

执行以下函数会将表 1 的 col2 中的所有 3 行设置为 D。

UPDATE T1
SET col2 = T2.col2
FROM #TEMP T1 INNER JOIN #TEMP2 T2 ON T2.col1 = T2.col1

下面的代码说明了示例:

SELECT 1 AS col1,'A' as col2 INTO #TEMP
INSERT INTO #TEMP
SELECT 1, 'B'
INSERT INTO #TEMP
SELECT 1, 'C'

SELECT 1 AS col1,'D' as col2 INTO #TEMP2
INSERT INTO #TEMP2
SELECT 1, 'E'
INSERT INTO #TEMP2
SELECT 1, 'F'

--SELECT * FROM #TEMP T1 INNER JOIN #TEMP2 T2 ON T2.col1 = T2.col1
--Result of below join

UPDATE T1
SET col2 = T2.col2
FROM #TEMP T1 INNER JOIN #TEMP2 T2 ON T2.col1 = T2.col1

SELECT * FROM #TEMP

为什么#TEMP的col2取值D?为什么不是E或F? 这只是因为它是连接中的第一条记录而被获取吗?

谢谢

最佳答案

我认为documentation关于这个问题非常清楚。我已将最重要的部分加粗:

Use caution when specifying the FROM clause to provide the criteria for the update operation. The results of an UPDATE statement are undefined if the statement includes a FROM clause that is not specified in such a way that only one value is available for each column occurrence that is updated, that is if the UPDATE statement is not deterministic. For example, in the UPDATE statement in the following script, both rows in Table1 meet the qualifications of the FROM clause in the UPDATE statement; but it is undefined which row from Table1 is used to update the row in Table2.

换句话说,使用任意匹配行中的值。没有规定到底是哪一个。

设置特定值的便捷方法是使用apply:

UPDATE T1
    SET col2 = T2.col2
    FROM #TEMP T1 CROSS APPLY
         (SELECT TOP (1) t2.*
          FROM #TEMP2 T2 
          WHERE T2.col1 = T2.col1
          ORDER BY ?  -- this ordering specifies the prioritization for the assignment
         ) T2;

ORDER BY 指定要使用的行。

关于sql - 使用连接重复项更新语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50461747/

相关文章:

sql-server - 如何计算 SQL Server 中的到期日期?

sql-server - 查询以更改 SQL Server 2008 中的表排序规则

sql-server - 为什么除零后执行insert into语句会抛出异常

sql - SQL select语句显示不存在的列?

c# - 如何从我的应用程序处理 SQL 键值表?

php - SQL 和不区分大小写的条件

sql - 将数据类型 varchar 转换为 float 时出错

mysql - SQL 脚本,我的脚本准确吗?

mysql - 如何使用 WHERE 子句和 INNER JOIN 从列中获取所有行

php - 如何在 mySql 上加入 2 个表?