用于更新列中具有相同值的行的T-SQL

时间:2011-10-24 03:28:46

标签: sql-server tsql

我有一个名为FavoriteFruits的表,其列为NAMEFRUITGUID。该表已经填充了名称和水果。所以我们说:

NAME      FRUIT       GUID
John      Apple       NULL
John      Orange      NULL
John      Grapes      NULL
Peter     Canteloupe  NULL
Peter     Grapefruit  NULL

好的,现在我想用新的GUID(使用GUID)更新NEWID()列,但我希望每个不同的名称具有相同的GUID。所以我希望所有John Smiths都具有相同的GUID,我希望Peters具有相同的GUID,但GUIDNAME FRUIT GUID John Apple f6172268-78b7-4c2b-8cd7-7a5ca20f6a01 John Orange f6172268-78b7-4c2b-8cd7-7a5ca20f6a01 John Grapes f6172268-78b7-4c2b-8cd7-7a5ca20f6a01 Peter Canteloupe e3b1851c-1927-491a-803e-6b3bce9bf223 Peter Grapefruit e3b1851c-1927-491a-803e-6b3bce9bf223 不同一个用于约翰斯。所以现在它看起来像这样:

{{1}}

我可以在更新语句中执行此操作而无需使用游标吗?如果是这样,请举个例子?

谢谢你们......

3 个答案:

答案 0 :(得分:6)

更新 CTE将无效,因为it'll evaluate per row。表变量可以工作:

您应该能够使用表变量作为更新数据的源。这是未经测试的,但它看起来像:

DECLARE @n TABLE (Name varchar(10), Guid uniqueidentifier);

INSERT @n
SELECT Name, newid() AS Guid
FROM FavoriteFruits
GROUP BY Name;

UPDATE f
    SET f.Guid = n.Guid
FROM @n n
    JOIN FavoriteFruits f ON f.Name = n.Name

这样就可以使用每个名称的GUID填充变量,然后将其连接回原始表并相应地进行更新。

答案 1 :(得分:0)

USING语句的MERGE子句中重新表达注释​​。

以下内容无效,因为it'll evaluate per row

MERGE INTO FavoriteFruits
   USING (
          SELECT NAME, NEWID() AS GUID
            FROM FavoriteFruits
           GROUP 
              BY NAME
         ) AS source
      ON source.NAME = FavoriteFruits.NAME
WHEN MATCHED THEN
   UPDATE
      SET GUID = source.GUID;

但是,使用表变量的以下内容将起作用:

DECLARE @n TABLE 
(
 NAME VARCHAR(10) NOT NULL UNIQUE, 
 GUID UNIQUEIDENTIFIER NOT NULL UNIQUE
);

INSERT INTO @n (NAME, GUID)
   SELECT NAME, NEWID() 
     FROM FavoriteFruits
    GROUP 
       BY NAME;

MERGE INTO FavoriteFruits
   USING @n AS source
      ON source.NAME = FavoriteFruits.NAME
WHEN MATCHED THEN
   UPDATE
      SET GUID = source.GUID;

答案 2 :(得分:0)

也有单一语句解决方案,但是有一些限制。我的想法是使用OPENQUERY(),如下所示:

UPDATE FavoriteFruits
SET GUID = n.GUID
FROM (
  SELECT NAME, GUID
  FROM OPENQUERY(
    linkedserver,
    'SELECT NAME, NEWID() AS GUID FROM database.schema.FavoriteFruits GROUP BY NAME'
  )
) n
WHERE FavoriteFruits.NAME = n.NAME

此解决方案意味着您需要创建一个自我指向的链接服务器。另一个特点是你不能在表变量上使用这个方法,也不能在本地临时表中使用这种方法(全局表和普通表一样)。