2015-02-23 41 views
4

只是所以我有一些记录allready抓取。我有'创建'日期字段,现在我想按照日期获取下一个和前一个记录。学说 - 得到下一个和prev记录

得到它的工作:

$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(); 

它工作得很好。但这是数据库的两个问题。我需要一个。我可以通过加入等来做到这一点,但是当没有下一个或者没有prev时,我只能得到一个空数组。

有什么想法吗?

回答

5

亚历山大的反应是接近。当您查询id < 2 LIMIT 1时,它将返回1,但如果您查询id < 5 LIMIT 1,则此操作也将返回1。这是因为它返回1, 2, 3, 4并取第一个元素,即1而不是所需的4

只需添加ORDER BY id DESC即可获取上一项。这将返回4, 3, 2, 1,并且LIMIT 1将返回4或前一个元素。

$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); 
+0

啊...是的..你正确:)我忘了关于订购:) – 2015-04-20 17:31:37

2

您可以使用本机查询,您可以:

/** @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(); 

$用户变量,你将有如下数组:

[ 
    ['id' => 1] 
    ['id' => 3] 
] 

这里更多细节http://doctrine-orm.readthedocs.org/en/latest/reference/native-sql.html

0

当使用ORM实体存储库时,本机SQL的另一种方法。

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:

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 

(选择使用QueryBuilder的,而不是通过$this->_em->createQuery($DQL)

结果数据集:

array(2) { 
    [0]=> 
    array(1) { 
    ["id"]=> 
    string(4) "5869" 
    } 
    [1]=> 
    array(1) { 
    ["id"]=> 
    string(4) "5871" 
    } 
}