Search code examples
phpsqlzend-frameworkzend-dbzend-db-table

Zend_Db_Select query with UNION and IN operator


How can i write this query with Zend_Db_Select objects?

SELECT
    `v1`.`id`,
    `v1`.`title`,
    `v1`.`duration`,
    `v1`.`img`
FROM 
    `videos` AS `v1` 
WHERE 
    v1.id IN (
        SELECT id_video FROM videos_categories WHERE id_video NOT IN(
            select id_video from videos_categories where id_category=34
            UNION
            select id_video from videos_categories where id_category=20
        )
    )

I tried something like this but nothing works, i've got an error page. I use datamappers

$objQuery = $this->getDbTable()->select()
    ->from(array('v'=>'videos'),array('v.id','v.title','v.duration','v.img'))

$tableVC1 = new Application_Model_DbTable_VideosCategories(); 
$tableVC2 = new Application_Model_DbTable_VideosCategories();
$tableVC3 = new Application_Model_DbTable_VideosCategories();
$tableVC4 = new Application_Model_DbTable_VideosCategories();

// select id_video from videos_categories where id_category=20
$tableVC4->select()->from(array("vc"=>"videos_categories"),array("id_video"))
    ->where("vc.id_category=20");

// select id_video from videos_categories where id_category=34
$tableVC3->select()->from("videos_categories","id_video")
    ->where("id_category=34");

// union between previous queries
$tableVC2->select()->union(array($tableVC4,$tableVC3));

$tableVC1->select()->from("videos_categories","id_video")
    ->where("id_video NOT IN ?",$tableVC2);

$objQuery->where("v.id IN ?",$tableVC1);

Thx for helping me.


Solution

  • My guess is that you're trying to send an object to your union, when it expects a string.

    Try this:

    $objQuery = $this->getDbTable()
                     ->select()
                     ->from(array('v' => 'videos'),
                            array('v.id', 'v.title', 'v.duration', 'v.img'))
    
    $tableVC1 = new Application_Model_DbTable_VideosCategories(); 
    $tableVC2 = new Application_Model_DbTable_VideosCategories();
    $tableVC3 = new Application_Model_DbTable_VideosCategories();
    $tableVC4 = new Application_Model_DbTable_VideosCategories();
    
    // select id_video from videos_categories where id_category=20
    $select4 = $tableVC4->select()
                        ->from(array("vc" => "videos_categories"),
                               array("id_video"))
                        ->where("vc.id_category=20");
    
    // select id_video from videos_categories where id_category=34
    $select3 = $tableVC3->select()
                        ->from("videos_categories", "id_video")
                        ->where("id_category=34");
    
    // union between previous queries
    $select2 = $tableVC2->select()
                        ->union(array($select4, $select3));
    
    $select1 = $tableVC1->select()
                        ->from("videos_categories", "id_video")
                        ->where("id_video NOT IN ?", $select2);
    
    $objQuery->where("v.id IN ?", $select1);
    

    echo $objQuery; should output the expected query.