Подзапрос Zend_Db

Я пытался создать 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');

person user387302    schedule 10.07.2010    source источник


Ответы (1)


Подзапрос не нужен, это можно сделать с помощью 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-запрос и он не зависит от условий приложения, будет более понятным просто записать его в строку - точно так же, как вы написали в своем исходном вопросе.

person Bill Karwin    schedule 11.07.2010
comment
Спасибо за отзыв, я использую MySQL, но, к сожалению, это не дает желаемого результата. Я должен упомянуть, что не каждый td.ID имеет связанный ti.destination_id, и я думаю, поэтому мне лучше использовать подзапрос. Любые идеи? - person user387302; 11.07.2010
comment
Большое тебе спасибо! У меня все еще была проблема с подзапросом, поскольку он, казалось, генерировал правильный запрос, но был неправильно разграничен Zend_Db_Select (даже когда я пытался использовать Zend_Db_Expr). Так что я отказался от этого. Но благодаря вашему предложению я переработал свой запрос, чтобы использовать leftjoin / groupby, чтобы избежать необходимости в подзапросе. Большое тебе спасибо! У меня все еще есть другие части запроса, которые зависят от логики приложения, поэтому я хотел использовать zend_db_select для начала. - person user387302; 11.07.2010
comment
это сработало идеально для меня. здесь array("trip_title", "($subquery)")) я добавил array("trip_title", "($subquery) as subquery")), чтобы я видел только результат - person Patrioticcow; 10.12.2011
comment
что такое $ db? Как получить его ? - person Pratik; 28.01.2016
comment
@PratikCJoshi, это экземпляр класса Zend_Db_Adapter. Прочтите документацию, в ней рассказывается, как его создать, и некоторая основная информация о том, как его использовать: framework.zend.com/manual/1.12/en/zend.db.adapter.html - person Bill Karwin; 29.01.2016