更新 sql 得到 select 多行

update sql getting select more than one row

以下查询引发错误 [SQL0811]

表示SELECTreturn的结果不止一行。但是当我 运行 单独查询时,它们 return 每个键一行。

我想我需要另一个 WHERE 子句检查 table 2 和 table 1。但是我如何才能在 SELECT 和 table 2 之外看到 table 2进入WHERE子句?

我在 EXISTS 之前尝试过这样的事情:

where a.key1 = b.key1 and a.key2 = b.key2 and a.key3  b.key3, 

但是当我 运行 我得到错误:

column or global variable 'key1' not defined

UPDATE table 1 AS a
SET (a.col1, a.col2, a.col3) = (
    SELECT coalesce(b.col1, 'N'), coalesce(b.col2, 'N'), coalesce(b.col3, 'N')
    FROM table 2 b
    LEFT OUTER JOIN table 1 c
    ON b.key1 = c.key1
      AND b.key2 = c.key2
      AND b.key3 = c.key3
)
WHERE (a.col1 = ' ' OR a.col2 = ' ' OR a.col3 = ' ')
  AND EXISTS(
        SELECT 1
        FROM table c trk
                 INNER JOIN table d sts ON trk.key1 = sts.key1
        WHERE trk.key1 = a.key1
          AND sts.status IN (' ', 'REQ')
    )

我很确定您想要 set 查询的 相关子查询

UPDATE table1 a
    SET (a.col1, a.col2, a.col3) = (
        SELECT coalesce(b.col1, 'N'), coalesce(b.col2, 'N'), coalesce(b.col3, 'N')
        FROM table2 b
        WHERE b.key1 = a.key1 AND
              b.key2 = a.key2 AND
              b.key3 = a.key3
       )
    WHERE . . .;

编辑:

如果要保证SET中的子查询returns恰好是一行并且列永远不会是NULL,那么使用聚合:

UPDATE table1 a
    SET (a.col1, a.col2, a.col3) = (
        SELECT coalesce(MAX(b.col1), 'N'), coalesce(MAX(b.col2), 'N'), coalesce(MAX(b.col3), 'N')
        FROM table2 b
        WHERE b.key1 = a.key1 AND
              b.key2 = a.key2 AND
              b.key3 = a.key3
       )
    WHERE . . .;

Gordon 为您提供了 SQL0811 的原因以及解决方法。让我们分解更新语句:

UPDATE table 1 AS a
SET (a.col1, a.col2, a.col3) = (
    SELECT coalesce(b.col1, 'N'), coalesce(b.col2, 'N'), coalesce(b.col3, 'N')
    FROM table 2 b
    LEFT OUTER JOIN table 1 c
    ON b.key1 = c.key1
      AND b.key2 = c.key2
      AND b.key3 = c.key3
)
WHERE ...

您似乎在尝试从子查询更新 table 1。但是,该子查询与 a 没有任何联系。因此它返回 table 2 中的所有行加上 table 1 中的匹配行,其中没有匹配项的空值。由于 table 2 中有多行,您将得到 SQL0811。您需要按照 Gordon 的建议使用相关子查询,以避免为要更新的每一行返回 table 2 中的所有行。

UPDATE table 1 AS a
SET (a.col1, a.col2, a.col3) = (
    SELECT coalesce(b.col1, 'N'), coalesce(b.col2, 'N'), coalesce(b.col3, 'N')
    FROM table 2 b
    WHERE b.key1 = a.key1
      AND b.key2 = a.key2
      AND b.key3 = a.key3
)
WHERE ...

但是,对于 table 1 中的每一行,table 2 中似乎也没有一行,这就是你得到 SQL0407 的原因。为了防止这种情况,您只需要更新 table 1 中那些在 table 2 中有一行的行。这是通过将以下内容添加到外部 WHERE 子句来处理的:

UPDATE table 1 a
   ...
WHERE (key1, key2, key3) in (SELECT key1, key2, key3 FROM table 2)

现在,我突然想到,尽管您没有直接指定这一点,但您可能希望将 (col1, col2, col3) 设置为 ('N', 'N', 'N'),其中没有 table 2 行匹配 table 1 行。由于上面的例子只更新匹配的行,它不会获取不匹配的行。您可以使用单独的更新来执行此操作,或者要将这种可能性包含在与第一个更新相同的更新中,您需要将戈登的答案与查询的修改结合起来。你仍然需要相关的子查询,你仍然需要一个左连接,但是你需要来自 table 1 的所有行加上来自 table 2 的匹配行,而不是相反。看起来像这样:

UPDATE table 1 AS a
SET (a.col1, a.col2, a.col3) = (
    SELECT coalesce(c.col1, 'N'), coalesce(c.col2, 'N'), coalesce(c.col3, 'N')
    FROM table 1 b
    LEFT OUTER JOIN table 2 c
      ON b.key1 = c.key1
        AND b.key2 = c.key2
        AND b.key3 = c.key3
    WHERE a.key1 = b.key1
      and a.key2 = b.key2
      and a.key3 = b.key3
)
WHERE ...

为了完整起见,您写道:

I tried something like this before the EXISTS:

where a.key1 = b.key1 and a.key2 = b.key2 and a.key3 b.key3,

But when I run that I get the error:

column or global variable 'key1' not defined

那是因为b只在子select的范围内,在外层的where子句中找不到。所以 b.key1 没有在那里定义。如您所见,SQL 错误消息并不总是最好的。