如果“子查询返回超过1行”,则将其视为NULL

时间:2011-07-13 02:46:06

标签: mysql sql mysql-error-1242

我正在尝试将newtable上的商店ID与来自维护者的ID进行同步:

UPDATE newtable t SET t.store_id = (SELECT store_id FROM maintable s 
WHERE t.state = s.state AND s.city = t.city AND t.name = s.name)

每当子查询返回多行时,它就会出现“Subquery返回多于1行”的错误,但是当它返回零行时,子查询被认为没有返回任何内容,因此newtable上的store_id保持为NULL。这里没有什么新东西,它只是它的工作原理。

我想知道是否可以让子查询输出与没有匹配时的子查询输出相同,当它有多个匹配行时。

这样我就可以只在主表上的一个匹配行中同步store_id,并在子查询中出现多个匹配行时跳过。

3 个答案:

答案 0 :(得分:6)

我认为你可能正在寻找一个HAVING子句来强制查询恰好匹配一次:

UPDATE newtable t
SET t.store_id = (
    SELECT store_id
    FROM maintable s
    WHERE t.state = s.state
      AND s.city  = t.city
      AND t.name = s.name
    HAVING COUNT(*) = 1
)

这应该使多个匹配的行为与没有匹配相同。 HAVING子句几乎应用于查询过程的最后;如果没有WHERE匹配或多个匹配,那么COUNT(*) = 1将失败,内部查询将返回任何内容,但如果只有一行,则COUNT(*) = 1将成功,内部查询将返回单场比赛。

答案 1 :(得分:0)

您可以考虑在子查询中添加LIMIT 1,以便更好地实现您要完成的任务,具体取决于您的具体需求。

否则,您应该能够通过IF或CASE获得创意:

UPDATE newtable t SET t.store_id = (
    SELECT IF(num>1, NULL, storeid) FROM (
        SELECT COUNT(*) AS num, storeid FROM maintable s WHERE t.state=s.state AND s.city=t.city AND t.name=s.name
    )
)

未经测试,但应该让你进入球场。

答案 2 :(得分:0)

UPDATE newtable t SET t.store_id = IFNULL((SELECT store_id FROM maintable s 
WHERE t.state = s.state AND s.city = t.city AND t.name = s.name HAVING COUNT(*) = 1), t.store_id)

IFNULL(use_this_value_if_not_null,value_if_first_isnull)