簡體   English   中英

在選擇中推進子查詢

[英]Propel subqueries in select

我需要從數據庫中找到文章,以及鄰居的下一個和上一個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

怎么樣...

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

替代方法:

如果您的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

正如我所說:完全是另一種方法。 但是您必須接受:您不能將“邏輯上不相關”的三個查詢合並為一個。 即使您通過編程語言或數據庫抽象層中的巧妙方法使它看起來像它,也總是會導致數據庫引擎執行三個查詢!

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM