2

我需要从数据库中查找文章,以及邻居的下一个和上一个 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
4

2 回答 2

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

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

SELECT
    "19" AS prev,
    id
    "21" AS next
FROM
    articles;
于 2013-09-25T17:23:51.357 回答
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 对象,其中包含三个这样的“行”(假设您的 ArtId 再次为 20)

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

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

希望这可以帮助!

于 2013-10-03T17:02:10.150 回答