2010-01-22

【程式】ZF : Zend_Db_Table_Select - Sub Query

一直不想寫很複雜的SQL,但最終還是會遇到~~唉~~

這次的需求就是要從 A Table 中取得 ID。

再從 B Table 中,依 A.ID 與 B.AID 做對應,查出資料。

這部份就用到 Sub Query

附上我的程式範列:

# 程式在 A Model 
# 先從 A Model 查出需要的 ID
$tbSelect1 = $this->getTable()->select()
        ->from($this->getTable(),
            array('COUNT(*) AS CNT', 'AID'))
        ->order('CNT DESC')
        ->group('AID')
        ;

# 再跟 B Table 做 Join
$tbSelect2 = $this->getTable()->select()
        ->setIntegrityCheck(false)
        ->from(array('T' => $tbSelect1),
            array('T.AID')
            )
        ->where("T.CNT > 10")
        ->joinLeft('B',
            'T.AID = B.AID',
            array('B.TITLE', 'B.NAME'))
        ;

$res = $this->getTable()->fetchAll($tbSelect2)->toArray();

上面這程式最後產生出來的 SQL 為

SELECT "T"."AID", "B"."TITLE", "B"."NAME" FROM (
        SELECT COUNT(*) AS "CNT", "A"."MEDIA_ID"
            FROM "A" GROUP BY "AID" ORDER BY "CNT" DESC
    ) "T"
LEFT JOIN "B" ON T.ID = B.AID

 

然後還有另一種方式,是使用 IN 的方式。

# 程式在 A Model 
# 先從 A Model 查出需要的 ID
$tbSelect1 = $this->getTable()->select()
        ->from($this->getTable(),
            array( 'AID'))
        ->group('AID')
        ;

# 利用 IN 取得所需資料
$tbSelect2 = $this->getTable()->select()
        ->setIntegrityCheck(false)
        ->from('B'
            ,array('B.TITLE', 'B.NAME')
            )
        ->where(new Zend_Db_Expr("B.AID IN (". $tbSelect1." )"))
        ;

上面這段程式產生的 SQL 為

SELECT "B"."TITLE", "B"."NAME"
        FROM "B"
        WHERE (B.AID IN (
                SELECT "A"."MEDIA_ID" FROM "A" GROUP BY "AID"
        ))

就效能來看,目前好像是 第一種 Left Join 比較好。

但因為資料量少,也還沒辦法確定。待查~~

0 comments:

張貼留言