#mysql
#mysql
Вопрос:
Я уверен, что это нетрадиционно, однако я пытаюсь выполнить следующее:
У меня есть следующая таблица:
products_id, company_id, products_name
1, 1, shoes
1, 2, mens shoes
2, 1, pants
Теперь, что я хочу сделать, это выбрать конкретное products_name из этого, используя заданный products_id и company_id = ‘2’, однако во всех случаях, когда он не находит строку с company_id = ‘2’, я хочу, чтобы по умолчанию он давал мне products_name для того же product_id с ЛЮБЫМ company_id .
Например, если бы я искал products_id = ‘2’, company_id = ‘2’, он должен вернуть products_name = ‘pants’ . Однако, если бы я искал products_id = ‘1’, company_id = ‘2’, он должен вернуть ‘мужская обувь’. Если бы я искал products_id = ‘3’, company_id = что угодно — он должен вернуть пустой набор.
Мне нужно иметь возможность сделать это в одном операторе SQL, поэтому никакой обработки через PHP для подтверждения того, существует ли строка, скажем: products_id = ‘2’ company_id = ‘2’.
Фактическое приложение использует гораздо более сложную таблицу с несколькими объединениями, однако я не могу понять этот простой момент, поэтому, если кто-нибудь может помочь мне с этим препятствием, я был бы очень признателен.
Комментарии:
1. Запуск скрипта для всех, кто хочет поиграть с ним: sqlize.com/cS21282NZw
Ответ №1:
Вот запрос, который вернет продукт компании или любой общий, если для этой компании нет конкретного продукта, по всему списку продуктов. Его можно легко отфильтровать с добавлением where products_id = ##
в конце (или путем установки where
фильтра внутри двух внутренних подзапросов, которые на самом деле могут быть более эффективными):
set @company_id = 2;
select
coalesce(p2.products_id, p1.products_id) as products_id,
coalesce(p2.products_name, p1.products_name) as products_name
from
(select products_id, max(products_name) as products_name
from products group by products_id) p1
left join
(select products_id, products_name
from products where company_id = @company_id) p2
on p1.products_id = p2.products_id
Демонстрация: http://sqlize.com/pkt568O0b5
Основная идея моей логики заключалась в следующем:
- Создайте запрос, который вводит произвольное название продукта для каждого идентификатора продукта — просто извлекая название
max
продукта и группируя по идентификатору. - Создайте запрос, который извлекает название продукта для фильтруемой компании.
- Осталось соединить # 2 с # 1, чтобы у меня был список продуктов, а также название продукта для компании, если оно доступно. Из-за левого соединения все продукты все равно будут возвращены, но для продуктов, у которых нет определенного названия для данной компании, будет список для конкретной компании
NULL
. - Выберите идентификатор продукта и название из данного списка для конкретной компании, если таковые имеются. Если недоступно, используйте общий список, который просто извлекает
max
название продукта. Это обрабатывается с помощьюcoalesce
функции, которая возвращает первый ненулевой аргумент в своем списке. Таким образом, в основном сначала проверяется список, относящийся к конкретной компании, и, если ничего не доступно, вместо этого используется общий список.
Надеюсь, это поможет!
Комментарии:
1. Эй, большое спасибо за такой исчерпывающий ответ, после написания я подумал, что если я присоединю таблицу к самой себе, я, вероятно, буду на правильном пути, но эта функция объединения — недостающая часть! Теперь я перейду к кодированию этого в свой скрипт. Еще раз, большое вам спасибо, это действительно ценится.