Скажем, у меня есть 3 таблицы в MySQL:
Table 1: Person, with fields id and name
Table 2: Product, with fields id and name
Table 3: Transaction, with fields id, person_id and product_id
Теперь я хочу выполнить поиск в строке, чтобы получить список транзакций, в которых имя человека или имя продукта похоже на него.
Вот как я это делаю (Java-код с использованием hibernate, jpa и spring)
String str_query = "select tr from Transaction tr where
(tr.person.name like '%ANA%' or tr.product.name like '%ANA%')";
(сгенерированный SQL):
select
transaction_.id as col1,
transaction_.product_id as col2,
transaction_.person_id as col3
from
transaction transaction_ cross
join
person person1_ cross
join
product product1_
where
transaction_.person_id=person1_.id
and transaction_.product_id=product1_.id
and (
person1_.name like '%ANA%'
or product1_.name like '%ANA%'
);
Работает отлично.
Однако есть одно обстоятельство, при котором у него есть ошибка: Когда у меня есть транзакция, в которой либо Person, либо Product имеют значение null, даже если другой соответствует sql, он возвращает null.
Скажем, у меня есть человек с именем ANA CLARA и транзакция с его идентификатором и нулевым продуктом, тогда SQL возвращает null.
На чистом Mysql я бы сделал следующее:
and (transaction_.product_id=product1_.id or
transaction_.product_id is null)
Как я могу решить эту проблему на стороне Java?
Здесь отсутствует какой-то SQL ... В таблице транзакций нет столбца с именем name. Я подозреваю, что проблема связана с операциями внутреннего соединения с двумя другими таблицами. При внутренних соединениях, когда в одной из других таблиц не найдено соответствующей строки, запрос не вернет строку для этой транзакции. Я подозреваю, что нам нужны операции внешнего соединения, но спецификация не ясна (образцы данных и ожидаемый результат могли бы прояснить это) ... и показанный оператор не является допустимым синтаксисом MySQL. (Я не думаю, что проблема связана с обработкой NULL, проблема в том, что соответствующая строка не найдена.)
Привет, спасибо за поддержку, я обновил свой вопрос, добавив сгенерированный SQL и многое другое, что я узнал




Попробуйте это (не проверено):
SELECT tr
FROM Transaction tr
LEFT JOIN tr.person p ON p.name LIKE '%ANA%'
LEFT JOIN tr.product pr ON pr.name LIKE '%ANA%'
WHERE (NOT p IS NULL) OR (NOT pr IS NULL)
Работал как шарм! Спасибо :)
Не могли бы вы опубликовать несколько строк образцов данных и желаемый результат?