“子查询返回的值超过1。” SQL管理器中的错误

时间:2014-10-02 08:57:02

标签: sql sql-server

UPDATE Contact_UDF 
SET hasAttendedEvent = (
    SELECT CASE WHEN c.Contact_ID IN 
        (SELECT DISTINCT Contact_ID 
        FROM Action a 
        WHERE a.Action_Type_ID =39) THEN 1 ELSE 0 END
    FROM Contact c)

我正在运行这一小段SQL来在Contact_UDF表中设置一个标志但是仍然遇到以下错误:

  

Msg 512,Level 16,State 1,Line 1 Subquery返回的值超过1   值。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。声明已经终止。

我不能为我的生活理解为什么,因为我使用IN而不是它所描述的任何运算符。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:1)

要了解为什么会出现此错误,只需执行子查询并得出结论它确实返回多行:

SELECT CASE
              WHEN c.Contact_ID IN
                     (SELECT DISTINCT Contact_ID
                      FROM Action a
                      WHERE a.Action_Type_ID =39) THEN 1
              ELSE 0
          END
   FROM Contact c

它为Contact中的每条记录返回1行。

您忘记了在Contact_UDF和Contact之间进行1对1映射的条款:

UPDATE Contact_UDF udf
SET hasAttendedEvent =
  (SELECT CASE
              WHEN c.Contact_ID IN
                     (SELECT DISTINCT Contact_ID
                      FROM Action a
                      WHERE a.Action_Type_ID =39) THEN 1
              ELSE 0
          END
   FROM Contact c
   WHERE c.Contact_ID = udf.Contact_ID)

当然,这假定' c.Contact_ID = udf.Contact_ID'将子查询限制为一行。如果没有关于您的架构的更多信息,我无法确定这是真的。

答案 1 :(得分:0)

Popovitsj和Laurence的报道相当不错:

您的子查询可以返回多行,这些行的行为不像您在表达式中使用的值列表。但是,您可以使用exists函数来代替:

UPDATE Contact_UDF udf
SET hasAttendedEvent =
  (SELECT CASE
              WHEN exists (
                     (SELECT a.Contact_ID
                      FROM Action a
                      WHERE a.Action_Type_ID =39
                      and a.Contact_ID = c.Contact_ID) 
                      THEN 1
              ELSE 0
          END
   FROM Contact c
   WHERE c.Contact_ID = udf.Contact_ID)

有关存在函数的文档: (http://technet.microsoft.com/en-us/library/ms189259(v=sql.105).aspx

从子查询中的主查询引用列的文档: (http://technet.microsoft.com/en-us/library/ms189575(v=sql.105).aspx

答案 2 :(得分:-1)

试试这个:

UPDATE Contact_UDF SET hasAttendedEvent = (SELECT
CASE WHEN c.Contact_ID IN (SELECT TOP 1 Contact_ID FROM Action a WHERE a.Action_Type_ID =39)    THEN 1 ELSE 0 END
FROM Contact c)

看起来您的子查询可能返回超过1行。您需要确保它只返回1以使case语句起作用。以上修改将确保它只返回1.