SQL Server:选择有效的查询,但不更新。子查询问题

时间:2019-12-16 04:01:35

标签: tsql subquery

我对更新查询有疑问。

这是我尝试用来更新另一个名为BOARD_CALLS的表的表的摘录

表:BOARD_TASKS

   CHAR(8)     BIGINT      INT        INT           CHAR(8)             INT
+-----------+----------+----------+----------+-------------------+--------------+
| REF_CALL  | NUM_TASK | IS_PHONE | IS_EMAIL | IS_DUPLICATE_WITH | IS_DUPLICATE |
+-----------+----------+----------+----------+-------------------+--------------+
| CALL-345  | TASK3451 |    1     |    0     |        NULL       |       0      |
+-----------+----------+----------+----------+-------------------+--------------+
| CALL-345  | TASK3452 |    1     |    0     |        NULL       |       0      |
+-----------+----------+----------+----------+-------------------+--------------+
| CALL-345  | TASK3453 |    0     |    0     |      CALL-344     |       1      |
+-----------+----------+----------+----------+-------------------+--------------+
| CALL-346  | TASK3461 |    1     |    1     |        NULL       |       0      |
+-----------+----------+----------+----------+-------------------+--------------+
| CALL-347  | TASK3471 |    1     |    1     |        NULL       |       0      |
+-----------+----------+----------+----------+-------------------+--------------+
| CALL-347  | TASK3472 |    0     |    1     |        NULL       |       0      |
+-----------+----------+----------+----------+-------------------+--------------+
| CALL-348  | TASK3481 |    0     |    0     |      CALL-346     |       1      |
+-----------+----------+----------+----------+-------------------+--------------+

我使用两个规则:

当至少一个IS_PHONE / IS_EMAIL / IS_DUPLICATE = 1时,则目标表上的IS_PHONE / IS_EMAIL / IS_DUPLICATE = 1 其他0

当IS_DUPLICATE_WITH不为空时,我需要用电话号码填写IS_DUPLICATE_WITH

当我在BOARD_TASKS上进行选择时,一切正常,结果符合我的要求

以下是结果:

TABLE:BOARD_CALLS

+-----------+----------+----------+-------------------+--------------+
| REF_CALL  | IS_PHONE | IS_EMAIL | IS_DUPLICATE_WITH | IS_DUPLICATE |
+-----------+----------+----------+-------------------+--------------+
| CALL-345  |    1     |    0     |      CALL-344     |       1      |
+-----------+----------+----------+-------------------+--------------+
| CALL-346  |    1     |    1     |        NULL       |       0      |
+-----------+----------+----------+-------------------+--------------+
| CALL-347  |    1     |    1     |        NULL       |       0      |
+-----------+----------+----------+-------------------+--------------+
| CALL-348  |    0     |    0     |      CALL-346     |       1      |
+-----------+----------+----------+-------------------+--------------+

以下是我使用的选择查询:

SELECT REF_CALL,

MAX(IS_DUPLICATE_WITH) IS_DUPLICATE_WITH,
CASE WHEN COUNT(CASE WHEN IS_PHONE = '1' THEN 1 END) > 0 THEN 1 ELSE 0 END AS IS_PHONE,
CASE WHEN COUNT(CASE WHEN IS_EMAIL = '1' THEN 1 END) > 0 THEN 1 ELSE 0 END AS IS_EMAIL,
CASE WHEN COUNT(CASE WHEN IS_DUPLICATE = '1' THEN 1 END) > 0 THEN 1 ELSE 0 END AS IS_DUPLICATE

FROM BOARD_TASKS
WHERE IS_DUPLICATE_WITH IS NOT NULL 
OR IS_DUPLICATE = 1
OR IS_DUPLICATE = 0
OR IS_DUPLICATE IS NULL
GROUP BY REF_CALL

但是,一旦我尝试更新BOARD_CALLS,我就会收到2条错误消息

子查询返回了多个值。当子查询遵循=,!=,<,<=,>,> =

时,不允许这样做

空值通过聚合或其他设置操作消除

此处是我的更新查询

UPDATE T1

SET


T1.IS_DUPLICATE_WITH = (SELECT MAX(IS_DUPLICATE_WITH) 
                        FROM BOARD_TASKS WHERE IS_DUPLICATE_WITH IS NOT NULL 
                        OR IS_DUPLICATE = 1 
                        OR IS_DUPLICATE = 0 
                        OR IS_DUPLICATE IS NULL 
                        GROUP BY REF_CALL),

T1.IS_PHONE = (SELECT 
              (CASE WHEN 
               COUNT(CASE WHEN IS_PHONE = '1' THEN 1 END) > 0 
               THEN 1 ELSE 0 END) 
               FROM BOARD_TASKS 
               GROUP BY REF_CALL),

T1.IS_EMAIL = (SELECT 
              (CASE WHEN 
               COUNT(CASE WHEN IS_EMAIL = '1' THEN 1 END) > 0 
               THEN 1 ELSE 0 END) 
               FROM BOARD_TASKS 
               GROUP BY REF_CALL),

T1.IS_DUPLICATE = (SELECT 
                  (CASE WHEN 
                   COUNT(CASE WHEN BOARD_TASKS.IS_DUPLICATE = '1' THEN 1 END) > 0 
                   THEN 1 ELSE 0 END) 
                   FROM BOARD_TASKS 
                   GROUP BY REF_CALL)

FROM BOARD_CALLS T1
INNER JOIN BOARD_TASKS T2 ON T1.REF_CALL = T2.REF_CALL

BOARD_CALLS 已经在每列上具有默认值

REF_CALL:创建新呼叫(PK)时自动填充

IS_PHONE / IS_EMAIL / IS_DUPLICATE:0

IS_DUPLICATE_WITH:NULL

我真的不知道为什么它只能用于选择而不是更新

1 个答案:

答案 0 :(得分:0)

该错误消息非常具体,您正在尝试使用明显返回多行的查询来更新一列。您在帖子开头的select语句中显示了这一点。 例如,您的UPDATE语句的这一部分:

T1.IS_DUPLICATE_WITH = (SELECT MAX(IS_DUPLICATE_WITH) 
                        FROM BOARD_TASKS WHERE IS_DUPLICATE_WITH IS NOT NULL 
                        OR IS_DUPLICATE = 1 
                        OR IS_DUPLICATE = 0 
                        OR IS_DUPLICATE IS NULL 
                        GROUP BY REF_CALL)

试图将查询的所有值强制为一个值。这就是优化器要告诉您的。

另外,我不确定IS_DUPLICATE的所有可能值,但看来您正在列出所有这些值。如果是这样,则在WHERE子句中不需要任何它们。

请尝试一下,我没有任何DDL,因此可能存在语法错误,但这应该可以帮助您实现大部分目标:

UPDATE BOARDCALLS 
    SET IS_DUPLICATE_WITH = t2.IS_DUPLICATE_WITH,
        IS_PHONE = t2.IS_PHONE,
        IS_EMAIL = t2.IS_EMAIL,
        IS_DUPLICATE = t2.IS_DUPLICATE
FROM BOARDCALLS t1
INNER JOIN (
            SELECT REF_CALL,
            MAX(IS_DUPLICATE_WITH) IS_DUPLICATE_WITH,
            CASE WHEN COUNT(CASE WHEN IS_PHONE = '1' THEN 1 END) > 0 THEN 1 ELSE 0 END AS IS_PHONE,
            CASE WHEN COUNT(CASE WHEN IS_EMAIL = '1' THEN 1 END) > 0 THEN 1 ELSE 0 END AS IS_EMAIL,
            CASE WHEN COUNT(CASE WHEN IS_DUPLICATE = '1' THEN 1 END) > 0 THEN 1 ELSE 0 END AS IS_DUPLICATE

            FROM BOARD_TASKS
            WHERE IS_DUPLICATE_WITH IS NOT NULL 
            OR IS_DUPLICATE = 1
            OR IS_DUPLICATE = 0
            OR IS_DUPLICATE IS NULL
            GROUP BY REF_CALL) t2 ON t1.REF_CALL = t2.REF_CALL