2015-02-23 39 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" 
    } 
}