首页 > 解决方案 > SQL 通过基于表行选择一个值来更新另一个表中的字段

问题描述

我有一个数据库表,其中包含由数据创建工具创建的随机个人详细信息。

我想使用该表中的值来更新另一个表中的字段,以便在我们对另一台服务器上的问题进行故障排除时掩盖实时的个人详细信息。

表格如下:


表 1:tblRandom_Data

字段:名字 | 姓


表 2:tblCustomers

字段:客户 ID [GUID] | 名字 | 姓氏 | 地址第一行..........


我想通过从 tblRandom_Data 中选择一个随机的 First_Name 值来更新 tblCustomers 中所有行的 First_Name 字段。

我尝试了以下方法,但这会更新所有具有相同随机名字的行。所有值不需要是唯一的,但需要有一些差异。

Update tblCustomers 
        SET First_Name = (SELECT TOP 1 First_Name 
                          FROM tblRandom_Data
                          ORDER BY NEWID()
                         )

标签: sqlsql-servertsql

解决方案


问题是 SQL Server 将查询“优化”为只运行一次子查询。

我发现最简单的解决方案是关联子句——即使该子句毫无意义。假设tblCustomers.First_Name从不NULL

UPDATE c 
    SET First_Name = (SELECT TOP 1 First_Name 
                      FROM tblRandom_Data rd
                      WHERE rd.First_Name <> c.First_Name
                      ORDER BY NEWID()
                     )
FROM tblCustomers c;

另一种方法是通过值“循环”:

UPDATE c
    SET First_Name = rd.First_Name
    FROM (SELECT c.*,
                 ROW_NUMBER() OVER (ORDER BY NEWID()) as seqnum
          FROM tblCustomers c
         ) c JOIN
         (SELECT rd.*,
                 ROW_NUMBER() OVER (ORDER BY NEWID()) as seqnum,
                 COUNT(*) OVER () as cnt
          FROM tblRandom_Data rd
         ) rd
         ON (c.seqnum % rd.cnt) = rd.seqnum - 1;

这还具有“平衡”名称的好处。因此,如果客户的数量多于另一个表中的行数,则名称将被分配大约相同的次数。


推荐阅读