如果至少有一条记录符合条件,则使用相同的布尔值更新所有记录?

时间:2014-01-08 16:30:45

标签: sql sql-server

我想知道他们是否正在尝试更新一组记录是最好的方法,或者是否有更有效的方法来处理这个问题。

示例表:

    CREATE TABLE [dbo].[ListItems] (
    [Id] int NOT NULL IDENTITY(1,1) ,
    [EmailAddress] nvarchar(MAX)  NULL ,
    [FirstName] nvarchar(MAX) NULL ,
    [LastName] nvarchar(MAX)  NULL ,
    [IpAddress] nvarchar(MAX) NULL,
    [IsUnsubscribed] bit,
    [Md5Hash] varchar(250) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [ListId] int,
    CONSTRAINT [FK_dbo.ListItems_dbo.Lists_ListId] FOREIGN KEY ([ListId]) REFERENCES [dbo].[Lists] ([Id]) ON DELETE CASCADE ON UPDATE NO ACTION
    )


CREATE INDEX [IX_MD5] ON [dbo].[ListEmailItems]
([Md5Hash] ASC) 
WITH (FILLFACTOR = 80)
ON [PRIMARY]
GO

用户可以是多个列表的一部分,如果从特定列表中取消订阅,则会有一个标记。有时用户希望从所有列表中删除。每个列表的ID都不同,所以我不能将ID用作标识符。我有一个关于Md5Hash的索引,所以我使用它,因为它对每个电子邮件地址都是唯一的。这就是我在那种情况下到目前为止设置的内容,但是如果要查看大量记录,则速度很慢:

Update ListItems set IsUnsubscribed = 1 where IsUnsubscribed = 0 and  Md5Hash in (Select Md5Hash from ListItems where IsUnsubscribed = 1)

如果有更好的方法,我很好奇。

1 个答案:

答案 0 :(得分:4)

这和你要做的一样好,但我可能会把它重新写成EXISTS

UPDATE li
  SET IsUnsubscribed = 1
  FROM dbo.ListItems AS li -- always use schema prefix!
  WHERE IsUnsubscribed = 0
  AND EXISTS
  (
    SELECT 1 FROM dbo.ListItems
      WHERE Md5Hash = li.Md5Hash
      AND IsUnsubscribed = 1
  );

当然,另一个想法是在查询时检查是否存在至少一个1值,而不是经常运行此查询以将所有值保持在1。这是忙碌的工作,没有充分的理由。

我仍然认为您可以以对周围基础架构透明的方式将此状态抽象到另一个表(如I suggested in my comment)中。视图,同义词,通过存储过程强制执行数据访问等都可以帮助...