Резервное значение в условии JOIN, если строка не найдена

0

Предисловие: Я боюсь, что я прошу сделать то, чего не может быть достигнуто. Но я знаю, что, если есть способ сделать это, здесь кто-то будет знать :)

Предположим, у меня есть база данных MySQL (или MariaDB, если совместимость может быть сохранена). Мне нужно выбрать из TableA и присоединиться к TableB на основе определенного столбца, имеющего определенное значение X; возможно, в таблице Б нет подходящей строки, что означает, что я буду использовать ЛЕВЫЙ ВНЕШНИЙ СОЕДИНЕНИЕ. Однако, если ни одна строка не найдена (ни одна строка TableB не имеет значения X в этом столбце), то я хочу использовать строку из TableB со значением Y. Другими словами, Y должен действовать как условие возврата для JOIN.

Вот мой конкретный пример. Предположим, что я обрабатываю локализацию данных путем разделения объекта (например, продукта) между двумя таблицами, один с локализуемыми данными, а другой с фиксированными данными. Когда я хочу получить информацию о продукте на французском языке, я хочу вернуться на английский язык, если на французском языке информации нет. Однако, если я это сделаю

// basic stub of the query for demonstration purposes
SELECT * FROM Products p
LEFT OUTER JOIN ProductsLocalization pLoc
      ON pLoc.ProductID = p.ID AND pLoc.Culture = 'fr-FR'

Я получу NULL, если никакая французская информация недоступна. Вместо этого, только для этих строк, я хочу получить результат запроса

// basic stub of the query for demonstration purposes
SELECT * FROM Products p
LEFT OUTER JOIN ProductsLocalization pLoc
      ON pLoc.ProductID = p.ID AND pLoc.Culture = 'en-US'

Но, конечно, последний запрос неприемлем.

Я знаю, что я мог бы использовать OR для присоединения, основанный на том, что культура была "fr-FR" или "en-US", но это потенциально удвоило бы количество выбранных строк, и мне потребовалось бы отправить обработанный результирующий набор данных. Я хочу знать, есть ли способ избежать этой пост-обработки.

Недвойственный отказ от ответственности: мой вопрос похож на многие другие, но есть решающее различие. Мне нужно использовать резервное значение для самого условия JOIN, а не как результат запроса. Мое значение по умолчанию не входит в набор данных, но набор данных вычисляется на основе этого значения по умолчанию.

Теги:
mariadb

1 ответ

1
Лучший ответ

Вы можете присоединиться дважды и использовать COALESCE(), чтобы получить нужное значение:

SELECT p.product_desc, 
    COALESCE(pLoc_fr.value, pLoc_en.value) 
FROM Products p
    LEFT OUTER JOIN ProductsLocalization pLoc_us ON 
       pLoc_us.ProductID = p.ID 
       AND pLoc_us.Culture = 'en-US'
    LEFT OUTER JOIN ProductsLocalization pLoc_fr ON 
       pLoc_fr.ProductID = p.ID 
       AND pLoc_fr.Culture = 'fr-FR';

Кроме того, если вы можете представить себе способ комбинирования наборов данных, вы, вероятно, можете достичь использования plain-ol SQL. Некоторым краевым случаям требуется динамически генерировать SQL-запрос, но они не очень распространены. В этом случае вы также можете использовать два коррелированных подзапроса внутри COALESCE или CASE или оператора IF внутри SELECT. Там почти всегда есть несколько способов кожи кошки.

  • 0
    Я слишком часто забываю силу COALESCE (). Спасибо за ваш ответ: это работает, и я отмечаю это как правильный.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню