2012-04-13 13 views
1

Wie kann ich diese Abfrage mit Zend_Db_Select Objekten schreiben?Zend_Db_ Abfrage mit UNION und IN Operator auswählen

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

Ich habe so etwas versucht, aber nichts funktioniert, ich habe eine Fehlerseite. Ich verwende Datamapper

$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 für die Hilfe.

+0

Welche Art von "Fehlerseite" haben Sie? – Liyali

+0

Anwendungsfehler ... nichts zeigt, ich habe versucht, eine $ objQuery -> __ toString(), aber nichts wieder –

Antwort

1

Meine Vermutung ist, dass Sie versuchen, Senden Sie ein Objekt an Ihre Union, wenn es eine Zeichenfolge erwartet.

Versuchen Sie folgendes:

$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; ausgeben sollte die erwartete Abfrage.

+0

Thx Liyali !!! es funktioniert ... kannst du mir bitte erklären warum es jetzt funktioniert? Ich übergebe das gleiche Obj an die $ select var –

+0

'$ select [1 | 2 | 3 | 4]' sind eine Instanz von 'Zend_Db_Select', die eine' __toString() 'Methode implementiert. Wenn Sie '$ tableVC1' direkt an Ihre Union (oder where-Klausel) übergeben, bedeutet das, dass Sie versuchen, eine Instanz von' Application_Model_DbTable_VideosCategories' zu übergeben. – Liyali

0

Sie müssen Klammern um die?. => (?) ... und die Variable muss ein select-Objekt sein.

Zum Beispiel in dieser Zeile:

$tableVC2 = $xyz->select()... 

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

Ich versuchte, aber ich arbeite nicht –

+0

Ich posten eine andere Antwort, vielleicht hilft dies Ihnen. – ryu

0

Versuchen Sie SELECT-Anweisungen wie diese bauen, ohne Modelle - es sollte so funktionieren:

$db = Zend_Db_Table::getDefaultAdapter(); 
$select = $db->select() 
    ->from(
     // base table 
    ) 
    ->joinLeft(
     // join sth 
    ) 
    ->where('x = ?', $x) 
    ->where('y = ?', $y) 
    ->order('z DESC') 
    ->limit(10, 0); 
$q = $db->query($select); 
$rowSet = $q->fetchAll(); 
+0

Ich habe mehr als 1 Million Datensätze Datenbank, das Problem ist, dass ich UNION und IN-Operator brauche, die gleiche Abfrage mit einem Beitritt dauert 2 Minuten, mit IN und UNION nur 0,020 Sekunden –

+0

Ich meinte nicht, Sie sollten Joins verwenden. Ich meinte, du solltest diese Art von Select-Anweisung verwenden. Auf diese Weise können Sie die Variable $ select (das vollständige select-Objekt) im where-Methodenaufruf einer anderen select-Anweisung verwenden. Wenn Sie es mit Modellen tun, beschwert sich Zend über Tabellenbeschränkungen - meiner Erfahrung nach. – ryu