Я пытаюсь построить sql-запрос с ZendFW, но я не могу заставить его функционировать, как я хочу (или вообще работать). Это запрос, который работает, который я пытаюсь построить с помощью zend_db select ()
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
Я не могу понять, как правильно получить этот подзапрос там, и я ничего не пытаюсь работать.
Любая помощь будет принята с благодарностью!
Благодаря!
Редактирование / Ответ. Если у кого-нибудь будет такая же проблема, на основании приведенного ниже предложения я повторно обработал запрос следующим образом:
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
который с помощью ZendFW я создал таким образом:
$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');
Вам не нужен подзапрос, вы можете сделать это с помощью 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");
Я предполагаю, что вы используете MySQL. Группировка проще, потому что это разрешительное нестандартное поведение MySQL.
edit: Я изменяю вышеуказанный запрос для использования joinLeft()
для ti. Это в случае, если для вашего адресата не существует никаких приглашений, как вы упомянули в своем комментарии.
Если вам действительно нужно использовать подзапрос, вы можете создать его отдельно, а затем интерполировать его в список выбора вашего основного запроса:
$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 знает, как искать скобки в столбце, указанном в вашем списке, и пропускать такие столбцы.
Также я хотел бы указать, что вам не нужно использовать Zend_Db_Select только потому, что он есть. Этот класс лучше всего подходит, когда вам нужно создать запрос с частями, зависящими от переменных или логики приложения. Если вы знаете полный SQL-запрос и не зависят от условий приложения, более просто написать его в строке – точно так же, как вы писали в исходном вопросе.