Я перестраиваю ванильное приложение PHP / MySQL с использованием CakePHP 3.5.13.
Один из запросов в исходном приложении должен создать условие JOIN
для той же таблицы и делает это с помощьюпсевдонимы отдельных таблиц.Запрос выглядит следующим образом - и дает правильные результаты, которые мы ожидаем:
SELECT DISTINCT(s.id) FROM substances s
JOIN display_substances AS dsUses
ON (s.id = dsUses.substance_id AND dsUses.display_id = 128 AND (dsUses.value LIKE '%dye%') )
JOIN display_substances AS displays
ON (s.id = displays.substance_id AND displays.display_id NOT IN (1,2,3,4,6,128) AND (displays.value LIKE '%bpr%'))
Причина, по которой это необходимо, заключается в том, что запрос выполняет поиск 2 отдельных элементов ввода пользователя - в пределах одной таблицы (display_substances
), но против различных полей display_substances .display_id
.В терминах запроса выше это означает:
- Поиск
"%dye%"
, где display_id = 128
- Поиск
"%bpr%"
, где display_id
- , а не 1,2,3,4,6 or 128
В Cake я написал это так в контроллере, который обрабатывает функции поиска:
$query = $Substances->find()->select(['id' => 'Substances.id'])->distinct();
// Search for "dye"
$query = $query->matching('DisplaySubstances', function ($q) use ($uses_summary) {
return $q->where([
'DisplaySubstances.value LIKE' => '%dye%', // "dye" is dynamic and comes from $uses_summary
'DisplaySubstances.display_id' => 128
]);
});
// Search for "bpr"
$query = $query->matching('DisplaySubstances', function ($q) use ($regulatory_information) {
return $q->where([
'DisplaySubstances.value LIKE' => '%bpr%', // "bpr" is dynamic and comes from $regulatory_information
'DisplaySubstances.display_id NOT IN' => [1,2,3,4,6,128]
]);
});
Это приводит к неправильному SQL, потому что когда я отлаживаю $query->sql();
это дает другое JOIN
условие:
INNER JOIN display_substances DisplaySubstances ON
(
DisplaySubstances.value like "%dye%" AND DisplaySubstances.display_id = 128
AND DisplaySubstances.value like "%bpr%"
AND DisplaySubstances.display_id not in (1,2,3,4,6,128)
AND Substances.id = (DisplaySubstances.substance_id)
)
Я не уверен, как переписать этот запрос так, чтобы он обрабатывал каждый из двух входных данных поиска как условие JOIN
, согласнооригинальный запрос.
Главное, что я заметил, - это то, что исходный запрос имеет отдельные псевдонимы для одной и той же таблицы (AS dsUses
и AS displays
).Я не уверен, что это актуально?
Буду признателен за любую помощь здесь.Я пытаюсь использовать ORM вместо написания SQL вручную, поэтому предпочел бы знать, как использовать его для этого.