если «Подзапрос возвращает более 1 строки», считается NULL - PullRequest
3 голосов
/ 13 июля 2011

Я пытаюсь синхронизировать идентификаторы магазинов на newtable с идентификаторами из maintable здесь:

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 строки», но когда он возвращает ноль строк, считается, что подзапрос ничего не возвратил, поэтому store_id для newtable остается NULL. Здесь нет ничего нового, просто как это работает.

Я хотел бы знать, возможно ли позволить подзапросу выводить то же самое, что и при отсутствии совпадений, когда у него более одной совпадающей строки.

Таким образом я бы синхронизировал store_id только для ОДНОЙ совпадающей строки в основной таблице и пропускал, когда в подзапросе выходило более одной совпадающей строки.

Ответы [ 3 ]

6 голосов
/ 13 июля 2011

Я думаю, что вы, возможно, ищете условие 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 завершится успешно, и внутренний запрос вернет это единственное совпадение.

0 голосов
/ 13 июля 2011
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 голосов
/ 13 июля 2011

Возможно, вы захотите добавить 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
    )
)

Не проверено, но вы должны попасть на стадион.

...