2010-07-10 10 views
5

He estado tratando de construir una consulta sql con ZendFW, pero parece que no puedo hacer que funcione como quiero (o que funcione). Esta es la consulta que obras que yo estoy tratando de construir con Zend_Db seleccione()Zend_Db subconsulta

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 

Lo que no puedo entender es cómo conseguir que adecuadamente subconsulta allí, y nada que intento parece funcionar.

¡Cualquier ayuda sería muy apreciada!

Gracias!

Editar/Respuesta: Si alguien tendrá nunca un problema similar, basado en la sugerencia de abajo me re-trabajado por la consulta de la siguiente manera:

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 

el que el uso de ZendFW he creado de esta manera:

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

Respuesta

5

no necesita una subconsulta, se puede hacer esto 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"); 

Supongo que está utilizando MySQL. El modo agrupar es más simple por el comportamiento permisivo no estándar de MySQL.

editar: Cambio la consulta anterior para usar joinLeft() para ti. Esto es en caso de que no existan invitaciones para un destino dado, como mencionas en tu comentario.


Si realmente necesita usar una sub consulta, puede crear por separado y luego interpolar en la lista de selección de la consulta principal:

$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 sabe que buscar paréntesis en el columna nombrada en su lista de selección y omitir delimitar tales columnas.

También me gustaría señalar que no tiene que usar Zend_Db_Select solo porque está allí. Esa clase es mejor para cuando necesita construir una consulta con partes que dependen de variables o lógica de aplicación. Si conoce la consulta SQL completa y no depende de las condiciones de la aplicación, es más claro simplemente escribirla en una cadena, tal como lo escribió en su pregunta original.

+0

Gracias por sus comentarios, y estoy usando MySQL, pero desafortunadamente eso no produce el resultado que estoy buscando. Debo mencionar que no todos los td.ID tienen un ti.destination_id asociado, y creo que es por eso que es mejor utilizar una subconsulta. ¿Algunas ideas? – user387302

+0

¡Muchas gracias! Todavía tenía un problema con la subconsulta, ya que parecía generar la consulta correcta, pero Zend_Db_Select delimitó erróneamente (incluso cuando traté de usar Zend_Db_Expr). Así que renuncié a eso. Pero gracias a su sugerencia, modifiqué mi consulta para usar un leftjoin/groupby para evitar la necesidad de la subconsulta. ¡Muchas gracias! Todavía tengo otras partes de la consulta que dependen de la lógica de la aplicación y es por eso que quería usar zend_db_select para empezar. – user387302

+0

esto funcionó perfecto para mí. aquí "' array ("trip_title", "($ subquery)")) 'agregué' array ("trip_title", "($ subquery) como subconsulta")) 'para que vea el resultado solamente – Patrioticcow