Няколко години закъснение, но трябва да посочите своите EXISTS
подзаявка SQL в SELECT
или WHERE
част с оператор на QueryBuilder, за разлика от използването на параметър.
Освен това от order
е запазена дума в MySQL, ще трябва да използвате кавички за идентификатор `
(обратна отметка), за да избегнете името на таблицата.
При използване на ORM; трябва да посочите FROM
израз, който препраща към обект, така че ще трябва да промените подхода си.
$connection = $this->em->getConnection();
$expr = $connection->getExpressionBuilder();
$qbSub = $connection->createQueryBuilder()
->select(['1'])
->from('`order`', 'o')
->leftJoin('o', '`payment`', 'p', $exor->eq('p.order_id', 'o.id'))
->where($expr->isNull('p.id'));
/**
* @return string "1" if a record exists, "0" otherwise
*/
$connection->createQueryBuilder()
->select('EXISTS(' . $qbSub->getSQL() . ')')
->execute()
->fetchColumn();
$qb
->setParameter('name', $value)
->execute();
Резултатен SQL
SELECT EXISTS(
SELECT 1
FROM `order` AS o
LEFT JOIN `payment` AS p
ON p.order_id = o.id
WHERE p.id IS NULL
);
Предлагам обаче да промените заявката си от съединение за изключване на съединение за включване с NOT EXISTS
. Това ще филтрира поръчките, които са били платени, извън вашия набор от резултати. Вместо да се опитвате да присъедините всяка поръчка към всяко плащане и да извлечете плащанията, които връщат null
. Драстично подобряване на производителността на заявката.
Пример db-fiddle
SELECT EXISTS (
SELECT 1
FROM `order` AS o2
WHERE NOT EXISTS(
SELECT NULL
FROM `order` AS o
INNER JOIN `payment` AS p
ON p.order_id = o.id
WHERE o2.id = o.id
)
)