Я использую Doctrine QueryBuilder для создания запроса, чтобы выбрать группу пользователей по их окончаниям электронной почты. У меня есть массив окончаний электронной почты, например ['@someservice.com', '@anotherservice.com' ]
.
Я знаю, что я могу выбрать строку в массиве через WHERE IN
:
$qb= $this
->createQueryBuilder('u')
->orderBy('u.id', 'asc')
->where('u.email IN (:emails)')
->setParameter('emails', [
'@someservice.com',
'@anotherservice.com'
]);
Тем не менее этот запрос для точных вхождений строки и, следовательно, запроса, конечно, вернет пустой набор результатов.
Вот почему я хочу сделать LIKE-поиск в массиве, но все же делаю что-то вроде:
$qb= $this
->createQueryBuilder('u')
->orderBy('u.id', 'asc')
->where('u.email LIKE IN (:emails)')
->setParameter('emails', [
'%@someservice.com',
'%@anotherservice.com'
]);
к сожалению, не удается. Есть ли какой-нибудь синтаксический сахар для выполнения такого запроса, или я должен сделать запрос с кучей вызовов orHaving
?
Я достиг чего-то подобного:
foreach($emailEndings as $index => $ending) {
$qb->orWhere("u.email LIKE :email$index");
$qb->setParameter("email$index", $ending);
}
Индекс имеет важное значение, поскольку в противном случае выбирается только последняя запись массива.
Имейте в orWhere
что если у вас есть несколько статей, в которых вы попадете в проблему из-за предложения orWhere
. Вы не можете изменить это в andWhere
, так как это приведет к пусту набору результатов. В этом случае вам нужно будет сгруппировать условия в Orx
для andWhere
как это:
/**
* @param QueryBuilder $qb
*/
protected function addInternalFilter(QueryBuilder $qb)
{
$conditions = [];
foreach ($this->emailEndings as $index => $ending) {
$conditions[] = "u.email LIKE :string$index";
$qb->setParameter("string$index", $ending);
}
if (empty($conditions)) {
throw new \LogicException('Conditions are empty.');
}
$qb->andWhere(new Orx($conditions));
}
Вы не можете этого сделать. % для LIKE, LIKE не используется с IN.
Вы можете справиться с ним только с помощью OR:
->where("u.email LIKE '%@someservice.com' OR u.email LIKE '%@anotherservice.com'")
LIKE IN
не является признанным синтаксисом SQL AFAIK и, следовательно, вероятно, не поддерживается. Это не мешает вам расширить его с помощью вспомогательной функции, которая преобразует его в нечто подобное этому решению .HAVING
, как всегда, последнее средство, это идеально вписывается вWHERE
.