SQL Server子查询返回了多个值。当子查询跟随(chars)或子查询用作表达式时,不允许这样做。

12

我正在尝试根据字段的出现情况来更新它们。如果它们只出现一次,我会更新一些状态字段。

我的当前代码如下:

UPDATE table1
SET statusField = 1
WHERE someID = (
               SELECT someID
               FROM table1
               GROUP BY someID HAVING COUNT(*) = 1
               )

这会返回一个类似于标题中的错误:子查询返回多个值。当子查询跟随 =、!=、<、<=、> 或 >= 时,不允许出现此情况,或者当子查询用作表达式时。

是否有其他同样易读/简单的解决方案?

3个回答

20

使用IN关键字代替等号运算符,像这样:

UPDATE table1
SET statusField = 1
WHERE someID IN (
           SELECT someID
           FROM table1
           GROUP BY someID HAVING COUNT(*) = 1
           )
使用=需要子查询返回恰好1个结果。IN关键字适用于列表。

1
非常感谢您指出这个问题!这次运行得非常完美。 - Nict
1
这里不需要使用 GROUP BY someID HAVING COUNT(*) = 1 - Alex Kudryashev
太棒了。谢谢! - Rob

3

你应该在子查询中连接你的表。虽然使用'in'也是可行的,但在你的情况下我建议使用exists:

UPDATE table1 x
SET statusField = 1
WHERE exists (
               SELECT null
               FROM table1
               WHERE x.someID = someID
               GROUP BY someID 
               HAVING COUNT(*) = 1
               )

为了获得更好的性能,我建议使用以下脚本(sqlserver-2008+):

;WITH x as
(
SELECT rc = count() over (partition by someID), statusField
FROM table1
)
UPDATE x
SET statusField = 1
WHERE rc = 1

1
谢谢!最终我使用了IN运算符,因为查询只需要运行不到50行,所以查询并不太大。不过,我会将这个加入我的工具库!再次感谢! :) - Nict

1
尝试这个:

使用Top

UPDATE table1
SET statusField = 1
WHERE someID = (
               SELECT TOP 1 someID
               FROM table1
               GROUP BY someID HAVING COUNT(*) = 1
               )

或者您可以使用IN子句。
UPDATE table1
SET statusField = 1
WHERE someID IN (
               SELECT someID
               FROM table1
               GROUP BY someID HAVING COUNT(*) = 1
               )

1
你的第一个建议不会返回有用的答案。 - t-clausen.dk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接