2010-07-10 12 views
5

Ho cercato di creare una query sql con ZendFW, ma non riesco a farlo funzionare come voglio (o funzionare affatto). Questa è la domanda che opere che io sto cercando di costruire con Zend_Db selezionare()Zend_Db subquery

SELECT tc.trip_title, td.ID, td.trip_id, 
    (SELECT count(*) FROM 'trips_invites' ti 
    WHERE ti.destination_id=td.ID AND ti.accepted ='NR') AS "pending_invites" 
FROM `trips_current` AS `tc`, `trips_data` AS `td` 
WHERE (tc.ID=td.trip_id) AND (tc.creator_id = '1') 
ORDER BY `trip_id` ASC 

Quello che non riesco a capire è come ottenere correttamente che subquery in là, e nulla provo sembra funzionare.

Qualsiasi aiuto sarebbe molto apprezzato!

Grazie!

Modifica/Risposta: Se qualcuno avrà mai un problema simile, basata su suggerimento di seguito ho ri-lavorato dalla query nel seguente modo:

SELECT `tc`.`trip_title`, `td`.`ID`, `td`.`trip_id`, count(TI.ID) 
FROM `trips_current` AS `tc` 
INNER JOIN `trips_data` AS `td` ON td.trip_id = tc.ID 
LEFT JOIN trips_invites AS TI ON ti.destination_id = td.id 
WHERE tc.creator_id = 1 AND ti.accepted='NR' 
GROUP BY td.id 
ORDER BY `trip_id` ASC 

che usando ZendFW ho creato in questo modo:

$select = $this->dblink->select() 
->from(array('tc' => 'trips_current'), 
     array('trip_title')) 
->join(array('td' => 'trips_data'), 
'td.trip_id = tc.id',     
     array('ID','trip_id')) 
->joinLeft(array('ti'=>'trips_invites'), 
    'ti.destination_id = td.id', 
    array('COUNT(ti.id)')) 
->where('tc.creator_id =?',1) 
->group('td.id') 
->order('trip_id'); 

risposta

5

non hai bisogno di una sottoquery, si può fare questo con GROUP BY:

$select = $db->select() 
    ->from(array("tc"=>"trips_current"), array("trip_title")) 
    ->join(array("td"=>"trips_data"), "td.trip_id = tc.ID", array("ID", "trip_id")) 
    ->joinLeft(array("ti"=>"trips_invites"), "ti.destination_id = td.ID", array("COUNT(*)") 
    ->where("tc.creator_id = ?", 1) 
    ->group(array("tc.ID", "td.ID")) 
    ->order("trip_id"); 

Suppongo che tu stia usando MySQL. Il group-by è più semplice in questo modo a causa del comportamento non standard permissivo di MySQL.

modifica: Ho modificato la query precedente per utilizzare joinLeft() per ti. Questo è nel caso in cui non esistano inviti per una data destinazione, come menzionato nel tuo commento.


Se avete veramente bisogno di usare una sottoquery, è possibile crearlo separatamente e poi interpolare in select-list della query principale:

$subquery = $db->select() 
    ->from(array("ti"=>"trips_invites", "COUNT(*)") 
    ->where("ti.destination_id = td.ID"); 

$select = $db->select() 
    ->from(array("tc"=>"trips_current"), array("trip_title", "($subquery)")) 
    ->join(array("td"=>"trips_data"), "td.trip_id = tc.ID", array("ID", "trip_id")) 
    ->where("tc.creator_id = ?", 1) 
    ->order("trip_id"); 

Zend_Db_Select sa per cercare parentesi nella colonna nominata nell'elenco di selezione e saltare delimitando tali colonne.

Inoltre vorrei sottolineare che non è necessario utilizzare Zend_Db_Select solo perché è lì. Questa classe è la migliore per quando è necessario creare una query con parti che dipendono da variabili o logica dell'applicazione. Se si conosce la query SQL completa e non dipende dalle condizioni dell'applicazione, è più semplice scriverlo in una stringa, proprio come è stato scritto nella domanda originale.

+0

Grazie per il feedback, e sto usando MySQL, ma sfortunatamente questo non produce il risultato che sto cercando. Devo dire che non tutti gli ID di td.ID hanno un ti.destination_id associato, e penso che sia per questo che sto meglio usando una sottoquery. Qualche idea? – user387302

+0

Grazie mille! Ho ancora avuto un problema con la sottoquery poichè sembrava generare la query giusta ma è stata delimitata dal Zend_Db_Select (anche quando ho provato a usare Zend_Db_Expr). Quindi ho rinunciato a questo. Ma grazie al tuo suggerimento, ho rielaborato la mia query per utilizzare leftjoin/groupby per evitare la necessità della subquery. Grazie mille! Ho ancora altre parti della query che dipendono dalla logica dell'applicazione ed è per questo che volevo usare zend_db_select per cominciare. – user387302

+0

questo ha funzionato perfettamente per me. qui "' array ("trip_title", "($ subquery)")) 'Ho aggiunto' array ("trip_title", "($ subquery) come sottoquery")) 'in modo che non si veda il risultato solo – Patrioticcow