更新 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 错误消息并不总是最好的。
以下查询引发错误 [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 错误消息并不总是最好的。