在select中推进子查询

时间:2013-09-24 12:25:03

标签: php mysql propel

我需要从数据库中找到文章,以及邻居的下一个和上一个id。 现在我有3个查询工作 - 前两个没有find()方法 - 我知道。

$artNext = ArticlesQuery::create()
            ->filterById(array('min' => $artId + 1))
            ->filterByActive(1)
            ->filterByType(1)
            ->select('Id')
            ->orderById(Criteria::ASC)
            ->limit(1);


$artPrev = ArticlesQuery::create()
            ->filterById(array('max' => $artId - 1))
            ->filterByActive(1)
            ->filterByType(1)
            ->select('Id')
            ->orderById(Criteria::DESC)
            ->limit(1);


$article = ArticlesQuery::create()
            ->filterByActive(1)
            ->filterById($artId)
            ->findOne();

如何组合插入artPrev和artNext子查询,如下面的查询(简化)

select id,
(select id from articles where id<77 ORDER BY id DESC limit 1 ) as prev,
(select id from articles where id>77 ORDER BY id ASC limit 1) as next
from articles 
where id=77

2 个答案:

答案 0 :(得分:1)

怎么样......

$artNext = ArticlesQuery::create()
        ->filterById(array('min' => $artId + 1))
        ->filterByActive(1)
        ->filterByType(1)
        ->select('Id')
        ->orderById(Criteria::ASC)
        ->limit(1);
        ->find();

$artPrev = ArticlesQuery::create()
        ->filterById(array('max' => $artId - 1))
        ->filterByActive(1)
        ->filterByType(1)
        ->select('Id')
        ->orderById(Criteria::DESC)
        ->limit(1);
        ->find();

$article = ArticlesQuery::create()
        ->filterByActive(1)
        ->filterById($artId)
        ->withColumn('Articles.Id','id')
        ->withColumn($artPrev->getId(),'prev')
        ->withColumn($artNext->getId(),'next')      
        ->findOne();

现在您可以这样使用它:

$nextString = $article->getNext();
$prevString = $article->getPrev();
$idString = $article->getId();

在这种情况下,“ - &gt; withColumn”就像一个子选择,只是先前确定的值:

SELECT
    "19" AS prev,
    id
    "21" AS next
FROM
    articles;

答案 1 :(得分:0)

替代方法:

如果您的ID增加1并且从未删除或省略,您可以执行以下操作:

$article = ArticlesQuery::create()
    ->filterByActive(1)
    ->filterById($artId)
    ->_or()
    ->filterById($artId-1)
    ->_or()
    ->filterById($artId+1)
    ->withColumn('Articles.Id','id')
    ->withColumn(('IF Articles.Id ='.$artId.',"current",(IF Articles.Id ='.$artId+1.',"next","prev"))','position')
    ->find();

这会给你一个带有三个“行”的$ article对象(Assumin你的ArtId再次为20)

(0) 
    id=19
    position=prev
(1) 
    id=20
    position=current
(2) 
    id=21
    position=next

正如我所说:完全是另一种方法。但您必须接受:您不能将三个不“逻辑相关”的查询合并为一个。即使你在编程语言或数据库抽象层中使用优雅的方法使它看起来像它,它总是会导致数据库引擎执行三个查询!

希望这有帮助!