SQL Server如何更新具有多个值的行?

时间:2014-08-12 10:07:12

标签: sql sql-server tsql

在临时表的更新语句中,SQL Server如何确定在返回多个值时使用哪个值,例如:

UPDATE A
SET    A.dte_start_date = table1.dte_start_date
FROM   #temp_table A
INNER JOIN table1 ON A.id = table1.id

在这种情况下,问题是为临时表中的每个id值返回多个dte_start_date。我正在处理的表格中没有索引或唯一值,所以我需要知道SQL Server将如何在不同的值之间进行选择。

2 个答案:

答案 0 :(得分:2)

这是不确定的。有关更好的理解,请参阅以下示例。虽然这里解释的场景并不完全相同,但它非常相似

当要从数据库中检索单个值时,还要使用带有查询的SET语句来设置值。例如:

SET @v_user_user_id = (SELECT u.user_id FROM users u WHERE u.login = @v_login);

原因:与Oracle不同,如果从用于填充变量的SELECT查询返回多行,则SQL Server不会引发错误。上面的查询将抛出异常,而以下内容不会抛出异常,变量将包含查询表中的随机值。

SELECT @v_user_user_id = u.user_id FROM users u WHERE u.login = @v_login;

答案 1 :(得分:1)

如果你有一个两个很多的关系,那么使用哪个值是不确定的。

在MS-SQL-Sever(> = 2005)中,我会使用CTE,因为它是一种使用ROW_NUMBER指定我想要的内容的可读方式。 CTE的另一个优点是您可以轻松更改它以进行选择而不是更新(或删除)以查看将会发生的情况。

假设您想要每个ID的最新记录(acc.to dte_start_date):

WITH CTE AS
(
    SELECT a.*, rn = ROW_NUMBER() OVER (PARTITION BY a.id 
                                        ORDER BY a.dte_start_date DESC)
    FROM #temp_table A
    INNER JOIN table1 ON A.id = table1.id
)
UPDATE A
SET    A.dte_start_date = table1.dte_start_date
FROM #temp_table A INNER JOIN CTE ON A.ID = CTE.ID
WHERE CTE.RN = 1