mysql - sumar - doctrina-obtener el siguiente y el registro anterior
siguiente registro php mysql (3)
solo para que tenga un registro ya recuperado. Tengo el campo de fecha ''creado'' y ahora quiero obtener el siguiente y el anterior por fecha.
Lo tengo trabajando por:
$qb = $this->createQueryBuilder(''a'');
$next = $qb->expr()->gt(''a.created'', '':date'');
$prev = $qb->expr()->lt(''a.created'', '':date'');
$prev = $qb->select(''partial a.{id,title,created}'')
->where($prev)
->setParameter(''date'', $date)
->orderBy(''a.created'', ''DESC'')
->setMaxResults(1)
->getQuery()
->getArrayResult();
$next = $qb->select(''partial a.{id,title,created}'')
->where($next)
->setParameter(''date'', $date)
->orderBy(''a.created'', ''DESC'')
->setMaxResults(1)
->getQuery()
->getArrayResult();
funciona muy bien Pero esto es 2 pregunta a la base de datos. Necesito uno. Puedo hacer esto solo por unirme, etc., pero cuando no hay próximo o no anterior, obtengo solo un conjunto vacío.
¿alguna idea?
Puede hacerlo con consultas nativas:
/** @var EntityManager $em */
$em = $this->getDoctrine()->getManager();
$rsm = new ResultSetMapping();
$rsm->addScalarResult(''id'', ''id'');
$query = $em->createNativeQuery(''SELECT id FROM users WHERE
id = (SELECT id FROM users WHERE id > 2 LIMIT 1)
OR
id = (SELECT id FROM users WHERE id < 2 LIMIT 1)'', $rsm);
$users = $query->execute();
en la variable $ users , tendrá la siguiente matriz:
[
[''id'' => 1]
[''id'' => 3]
]
Más detalles aquí http://doctrine-orm.readthedocs.org/en/latest/reference/native-sql.html
La respuesta de Alexandr está cerca. Cuando consultas para id < 2 LIMIT 1
, devolverá 1
, pero si consultas id < 5 LIMIT 1
, también devolverá 1
. Esto se debe a que devuelve 1, 2, 3, 4
y toma el primer elemento, que es 1
lugar de 4
.
Simplemente agregue ORDER BY id DESC
para obtener el elemento anterior. Esto devolverá 4, 3, 2, 1
y el LIMIT 1
devolverá 4
o el elemento anterior.
$query = $em->createNativeQuery(''SELECT id FROM users WHERE
id = (SELECT id FROM users WHERE id > 2 LIMIT 1)
OR
id = (SELECT id FROM users WHERE id < 2 ORDER BY id DESC LIMIT 1)'', $rsm);
Un enfoque alternativo al SQL nativo, cuando se usa un repositorio de entidades ORM.
namespace EntityNamespace;
use Doctrine/ORM/EntityRepository;
class MyEntityRepository extends EntityRepository
{
/**
* @param int $id
* @return array|int[]
*/
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();
//optionally enable caching
//$query->useQueryCache(true)->useResultCache(true, 3600);
return $query->getScalarResult();
}
}
DQL resultante:
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
(opcionalmente use en lugar de querybuilder a través de $this->_em->createQuery($DQL)
)
Dataset resultante:
array(2) {
[0]=>
array(1) {
["id"]=>
string(4) "5869"
}
[1]=>
array(1) {
["id"]=>
string(4) "5871"
}
}