子查询按预期工作,完整查询效果一切?

时间:2015-01-30 19:52:44

标签: sql subquery

我对SQL很新,但这对我来说毫无意义。也许我没有比较正确的列,使用错误的运算符,或类似的简单的东西,但子查询运行并按预期返回正确的信息。当所有东西一起运行时,它会影响我放入的所有条目。

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

按预期返回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

子查询运行并返回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给了我一个答案,让它工作得很好,但是,我想知道为什么在那里使用工作子查询会让它变得混乱。

2 个答案:

答案 0 :(得分:0)

我的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列中存储的值。

答案 1 :(得分:0)

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