if“子查询返回多于 1 行”将其视为 NULL

发布于 2024-11-23 21:19:06 字数 427 浏览 7 评论 0原文

我正在尝试将 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)

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

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

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

I'm trying to sync store ids on newtable with the ids from the maintable here:

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)

Whenever a subquery returns more than one row it errors out with "Subquery returns more than 1 row", but when it returns zero rows the subquery is considered to have returned nothing so the store_id on newtable remains NULL. Nothing new here, it's just how it works.

I'd like to know if it's possible to let the subquery output the same as what it does when it has no matches when it has more than one matching row.

This way I'd get the store_id synced only for ONE matching row on the main table and skipped when more than one matching row comes out in the subquery.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一人独醉 2024-11-30 21:19:06

我认为您可能正在寻找 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 将成功,内部查询将返回该单个匹配项。

I think you might be looking for a HAVING clause to force the query to match exactly once:

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
)

That should make multiple matches behave the same as no matches. The HAVING clause is applied almost at the very end of the query process; if there are no matches from the WHERE or more than one match, then COUNT(*) = 1 will fail and the inner query will return nothing but if there is exactly one row then COUNT(*) = 1 will succeed and the inner query will return that single match.

宣告ˉ结束 2024-11-30 21:19:06

您可以考虑在子查询中添加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
    )
)

未经测试,但应该可以让您达到大概水平。

You might consider putting a LIMIT 1 in your sub-query to better achieve what you are trying to accomplish, depending on your specific needs.

Otherwise, you should be able to get creative with IF or 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
    )
)

Untested, but should get you in the ballpark.

吻泪 2024-11-30 21:19:06
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)

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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文