Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Consulta Doctrine2 DBAL Existe


Alguns anos atrasado, mas você precisa especificar seu EXISTS subconsulta SQL dentro do SELECT ou WHERE parte de instrução do QueryBuilder, em vez de usar um parâmetro.

Além disso, desde order é uma palavra reservada no MySQL, você precisará usar aspas identificadoras ` (back-tick) para escapar do nome da tabela.

Ao usar o ORM; você deve especificar um FROM declaração que faz referência a uma entidade, então você precisaria mudar sua abordagem.
$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 resultante
SELECT EXISTS(
   SELECT 1
   FROM `order` AS o
   LEFT JOIN `payment` AS p
   ON p.order_id = o.id
   WHERE p.id IS NULL
);

No entanto, sugiro alterar sua consulta de uma associação de exclusão para uma associação de inclusão com NOT EXISTS . Fazê-lo vai filtrar os pedidos que foram pagos fora do seu conjunto de resultados. Em vez de tentar juntar todos os pedidos em todos os pagamentos e recuperar os pagamentos que retornam null . Melhorando drasticamente o desempenho da consulta.

Exemplo 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
    )
)