2010-07-10 13 views
5

J'ai essayé de construire une requête sql avec ZendFW, mais je n'arrive pas à la faire fonctionner comme je veux (ou fonctionner du tout). Ceci est la requête qui fonctionne que je suis en train de construire avec Zend_Db sélectionner()Sous-requête Zend_Db

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 

Ce que je ne peux pas comprendre comment obtenir correctement là-dedans que sous-requête, et rien que j'essaie semble fonctionner.

Toute aide serait grandement appréciée!

Merci!

Modifier/réponse: Si quelqu'un aura jamais un problème similaire, basé sur la suggestion ci-dessous je retravaillées par requête de la manière suivante:

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 

qui utilisant ZendFW j'ai créé de cette façon:

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

Répondre

5

vous n'avez pas besoin d'un sous-requête, vous pouvez le faire avec 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"); 

Je suppose que vous utilisez MySQL. Le group-by est plus simple à cause du comportement non-standard permissif de MySQL.

modifier: Je modifie la requête ci-dessus pour utiliser joinLeft() pour ti. C'est dans le cas où aucune invitation n'existe pour une destination donnée, comme vous le mentionnez dans votre commentaire.


Si vous avez vraiment besoin d'utiliser un sous-requête, vous pouvez créer séparément et interpoler ensuite dans la liste de sélection de votre requête 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 sait chercher entre parenthèses dans la colonne nommée dans votre liste de sélection et ignorer la délimitation de ces colonnes.

Aussi, je tiens à souligner que vous n'avez pas besoin d'utiliser Zend_Db_Select juste parce qu'il est là. Cette classe est la meilleure lorsque vous devez créer une requête avec des parties qui dépendent de variables ou de la logique de l'application. Si vous connaissez la requête SQL complète et qu'elle ne dépend pas des conditions de l'application, il est plus clair de l'écrire simplement dans une chaîne, comme vous l'avez écrit dans votre question initiale.

+0

Merci pour vos commentaires, et j'utilise MySQL, mais malheureusement, cela ne produit pas le résultat que je recherche. Je dois mentionner que tous les td.ID n'ont pas de ti.destination_id associé, et je pense que c'est pourquoi je préfère utiliser une sous-requête. Des idées? – user387302

+0

Merci beaucoup! J'ai toujours eu un problème avec la sous-requête car elle semblait générer la bonne requête mais s'est trompée par le Zend_Db_Select (même lorsque j'ai essayé d'utiliser Zend_Db_Expr). Alors j'ai abandonné ça. Mais grâce à votre suggestion, j'ai retravaillé ma requête pour utiliser un leftjoin/groupby pour éviter d'avoir besoin de la sous-requête. Merci beaucoup! J'ai encore d'autres parties de la requête qui dépendent de la logique de l'application, c'est pourquoi je voulais utiliser zend_db_select pour commencer. – user387302

+0

cela a fonctionné parfaitement pour moi. ici "' array ("trip_title", "($ subquery)")) 'J'ai ajouté' array ("trip_title", "($ subquery) comme sous-requête")) 'de sorte que le résultat n'apparaisse que – Patrioticcow