开发者

if "Subquery returns more than 1 row" consider it NULL

开发者 https://www.devze.com 2023-03-19 16:29 出处:网络
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

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 whe开发者_如何转开发n 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.


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.


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.


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)

0

精彩评论

暂无评论...
验证码 换一张
取 消