An alternative approach to native SQL using the ORM entity repository.
namespace EntityNamespace; use Doctrine\ORM\EntityRepository; class MyEntityRepository extends EntityRepository { public function filterNextPrevious($id) { $expr = $this->_em->getExpressionBuilder(); $qbNext = $this->createQueryBuilder('a') ->select(['MIN(a.id)']) ->where($expr->gt('a.id', ':id')); $qbPrevious = $this->createQueryBuilder('b') ->select(['MAX(b.id)']) ->where($expr->lt('b.id', ':id')); $query = $this->createQueryBuilder('m') ->select(['m.id']) ->where($expr->orX( $expr->eq('m.id', '(' . $qbNext->getDQL() . ')'), $expr->eq('m.id', '(' . $qbPrevious->getDQL() . ')') )) ->setParameter('id', $id) ->addOrderBy('m.id', 'ASC') ->getQuery();
Resulting DQL:
SELECT m.id FROM EntityNamespace\Entity m WHERE m.id = ( SELECT MIN(a.id) FROM EntityNamespace\Entity a WHERE a.id > :id ) OR m.id = ( SELECT MAX(b.id) FROM EntityNamespace\Entity b WHERE b.id < :id ) ORDER BY m.id ASC
(optionally, instead of using the query builder, use $this->_em->createQuery($DQL) )
Result Dataset:
array(2) { [0]=> array(1) { ["id"]=> string(4) "5869" } [1]=> array(1) { ["id"]=> string(4) "5871" } }
Another alternative to using the WHERE IN() is to use SELECT subqueries and, if necessary, add a common COUNT() to the base table.
This will allow you to assign the resulting value to the associated key and end the ORDER BY .
$expr = $this->_em->getExpressionBuilder(); $next = $this->createQueryBuilder('a') ->select($expr->min('a.id')) ->where($expr->gt('a.id', ':id')); $previous = $this->createQueryBuilder('b') ->select($expr->max('b.id')) ->where($expr->lt('b.id', ':id')); $query = $this->createQueryBuilder('o') ->select('COUNT(o.id) as total') ->addSelect('(' . $previous->getDQL() . ') as previous') ->addSelect('(' . $next->getDQL() . ') as next') ->setParameter('id', $id) ->getQuery(); return $query->getSingleResult();
DQL result:
SELECT COUNT(o.id) as total, ( SELECT MAX(b.id) FROM EntityNamespace\Entity b WHERE b.id < :id ) as previous, ( SELECT MIN(a.id) FROM EntityNamespace\Entity a WHERE a.id > :id ) as next FROM EntityNamespace\Entity o
Result Dataset:
array(3) { ["total"]=> string(4) "63156" ["previous"]=> string(4) "5869" ["next"]=> string(4) "5871" }