Search code examples
phpmysqlsymfonydoctrine-ormdql

How to make Entity/Table subquery Inner Join on itself - NativeQuery/DQL Symfony 2


I have this query (which is working fine).

$sql = 'select * from ps_message p1 INNER JOIN (SELECT MAX(p2.id) as max_id FROM ps_message p2 GROUP BY p2.thread_id) as max_table on p1.id = max_table.max_id';

I want to convert it for my Symfony2 project.

I have tried building the DQL query using createQueryBuilder() and Native Query with ResultSetMapping()/ResultSetMappingBuilder(), but no success yet.

P.s. With ResultSetMapping() i am unable to get the relation fields working. I have tried tinkering with addJoinedEntityResult(), etc..:

$rsm = new ResultSetMapping();
$rsm->addEntityResult('BaseBundle:PsMessage', 'p1');
$rsm->addFieldResult('p1', 'id', 'id');
$rsm->addFieldResult('p1', 'message_text', 'messageText');
$rsm->addFieldResult('p1', 'message_type', 'messageType');
$rsm->addFieldResult('p1', 'receiver_message_status', 'receiverMessageStatus');
$rsm->addFieldResult('p1', 'sender_message_status', 'senderMessageStatus');
$rsm->addFieldResult('p1', 'created_date', 'createdDate');
$rsm->addFieldResult('p1', 'modified_date', 'modifiedDate');

$rsm->addFieldResult('t1', 'thread_id', 'thread_id'); //Error
$rsm->addFieldResult('u', 'sender_id', 'sender'); //Error
$rsm->addFieldResult('t', 'thread_id', 'thread'); //Error
$rsm->addFieldResult('p2', 'thread_id', 'thread'); //Error

$sql = 'select * from ps_message p1 INNER JOIN (SELECT MAX(p2.id) as max_id FROM ps_message p2 GROUP BY p2.thread_id) as max_table on p1.id = max_table.max_id';
$query = $em->createNativeQuery($sql, $rsm);

Solution

  • I resolved the issue by using two queries.

    This one gets the latest message of the thread:

    $messages_max = $em->createQueryBuilder()
    ->select('max(m.id) as id')
    ->from('BaseBundle:PsMessage', 'm')
    ->groupBy('m.thread')
    ->getQuery()
    ->getResult();
    

    This one displays all the threads:

    $qb = $em->createQueryBuilder()
    ->select('message')
    ->from('BaseBundle:PsMessage', 'message')
    ->where('message.receiver = :id')
    ->orWhere('message.sender = :id')
    ->andWhere('message.id in (:maxIds)')
    ->orderBy('message.modifiedDate', 'desc')
    ->setParameter('id', $userId)
    ->setParameter('maxIds', $messages_max);