子查询按预期工作,完整查询影响一切?

Subquery works as expected, full query effects everything?

我是 SQL 的新手,但这对我来说毫无意义。也许我没有比较正确的列,使用了错误的运算符,或者类似的简单操作,但是子查询运行并且 returns 了预期的正确信息。当所有内容 运行 在一起时,它会影响所有条目以及我输入的内容。

SELECT ActiveLocationId 
FROM [AuroraFileServer].[dbo].[File] 
WHERE ActivePath LIKE 'C:\Videos\Archived\%'

Returns 32 个条目符合预期。

UPDATE [AuroraFileServer].[dbo].[File]
SET ActiveLocationId = 'dc31fbe6-5d2a-4c42-9960-df833fd0e9ee'
WHERE ActiveLocationId IN (SELECT ActiveLocationId 
    FROM [AuroraFileServer].[dbo].[File] 
    WHERE ActivePath LIKE 'C:\Videos\Archived\%')
GO

影响大约 200 多个条目,但仅影响路径为 C:\Videos\ ...(如 Data 或 Archived)的条目,而不影响路径为 C:\ProgramData\ ...的条目...

如果我将其更改为:

,它会做同样的事情
UPDATE [AuroraFileServer].[dbo].[File]
SET ActiveLocationId = REPLACE(ActiveLocationId, 'efc84e2c-800d-45f1-ab80-779d6f812a30', 'dc31fbe6-5d2a-4c42-9960-df833fd0e9ee')
WHERE ActiveLocationId IN (SELECT ActiveLocationId
      FROM [AuroraCore].[dbo].[DeviceEventFile] AS DEF
      JOIN [AuroraCore].[dbo].[DeviceEvent] AS DE
      ON DE.Id = DEF.DeviceEventId 
      JOIN [AuroraFileServer].[dbo].[File] AS F
      ON DEF.FilePath = F.ActivePath
      WHERE IsArchived = 1)
GO

子查询运行并且 returns 32 个条目,但是 运行 整个过程导致 200 多个条目受到影响。真正让我陷入困境的是,我遵循了与我的其他查询之一相同的设计,而且效果很好!

UPDATE [AuroraFileServer].[dbo].[File]
SET ActivePath = REPLACE(ActivePath, 'C:\Videos\Data', 'C:\Videos\Archived')
WHERE ActivePath IN (SELECT ActivePath 
    FROM [AuroraCore].[dbo].[DeviceEventFile] AS DEF
    JOIN [AuroraCore].[dbo].[DeviceEvent] AS DE
    ON DE.Id = DEF.DeviceEventId 
    JOIN [AuroraFileServer].[dbo].[File] AS F
    ON DEF.FilePath = F.ActivePath
    WHERE IsArchived = 1)
GO

我哪里做错了!?

编辑:这两个查询相互关联,因此它们应该只影响相同的 32 个条目。 spencer7593 给了我一个答案,让它工作得很好,但是,我想知道为什么在那里有工作子查询会使它变得混乱。

我没有看到任何东西 "wrong" 你的 UPDATE;但不清楚您要做什么。

影响 200 多行的更新,我们不希望它恰好匹配或更新 32 行。因为它在 ActiveLocationId 上匹配,而不是在 ActivePath.

上匹配
WHERE ActiveLocationId IN (SELECT ActiveLocationId 
      ^^^^^^^^^^^^^^^^            ^^^^^^^^^^^^^^^^

如果您的目的是仅更新匹配 ActivePath 的 32 行,则不需要子查询。只需这样做:

UPDATE [AuroraFileServer].[dbo].[File]
   SET ActiveLocationId = 'dc31fbe6-5d2a-4c42-9960-df833fd0e9ee'
 WHERE ActivePath LIKE 'C:\Videos\Archived\%'

如果出于某种原因您需要子查询,但您只想更新以特定字符串开头的 ActivePath 行,则在 UPDATE 查询中包含该谓词,而不仅仅是子查询。 ..

UPDATE [AuroraFileServer].[dbo].[File]
   SET ActiveLocationId = 'dc31fbe6-5d2a-4c42-9960-df833fd0e9ee'
 WHERE ActiveLocationId IN 
       ( SELECT ActiveLocationId 
           FROM [AuroraFileServer].[dbo].[File] 
          WHERE ActivePath LIKE 'C:\Videos\Archived\%'
       )
   AND ActivePath LIKE 'C:\Videos\Archived\%'

您的其他具有类似设计的查询匹配 ActivePath

WHERE ActivePath IN (SELECT ActivePath 
      ^^^^^^^^^^            ^^^^^^^^^^

我们注意到,这将更新具有匹配 ActivePath 的任何行,而不仅仅是满足子查询中谓词的行。子查询指定

WHERE IsArchived = 1

但是外部更新没有观察到那个谓词。外部更新将更新所有值为 ActivePath 且与子查询返回的集合中的值匹配的行,而不管存储在 IsArchived 列中的值如何。

好的,我认为问题是重复的。 activation path C:\Videos\Archived 有 32 个条目。此激活路径的 Activation Id's 还查找具有不同 activation Path's 的其他记录 activation IDactivation path 之间存在一对多关系。因此,如果您将 Activation Path 放在 Query1 和 query2 外部查询的 WHERE 条件中,您将获得相同的结果。