Подтвердить что ты не робот

Группировка предложений WHERE с помощью Zend_Db_Table_Abstract

Кто-нибудь знает способ группировки where clauses с Zend_Db? В основном у меня есть этот запрос

$sql = $table->select()
             ->where('company_id = ?', $company_id)
             ->where('client_email = ?', $client_email)
             ->orWhere('client_email_alt = ?', $client_email);

Что мне дает это:

SELECT `clients`.* FROM `clients` WHERE (company_id = '1') AND (client_email = '[email protected]') OR (client_email_alt = '[email protected]')

Но мне нужно это, чтобы дать мне это, где сгруппирован оператор OR:

SELECT `clients`.* FROM `clients` WHERE (company_id = '1') AND ((client_email = '[email protected]') OR (client_email_alt = '[email protected]'))
4b9b3361

Ответ 1

Чтобы достичь этого, вы должны построить предложение grouped в рамках одного вызова метода where.

Если оба значения условий одинаковы, вы можете сделать это:

$select->where('client_email = ? OR client_email_alt = ?', $client_email)

Если в строке есть несколько заполнителей, метод DB adapter quoteInto заменит все заполнители на предоставленное значение.

Если вам нужно сгруппировать OR с разными значениями для каждого поля, вам нужно вручную указать значения. Это немного сложнее:

$select->where(
    $db->quoteInto('client_email = ?', $email1) . ' OR ' . $db->quoteInto('client_email_alt = ?', $email2)
); // $db is your instance of Zend_Db_Adapter_*
   // You can get it from a Zend_Db_Table_Abstract 
   //subclass by calling its getAdapter() method 

Ответ 2

Вы можете использовать getPart(), чтобы получить инструкцию WHERE, а затем подключить подзапросы.

$select->where('client_email = ?', $client_email)
       ->orWhere('client_email_alt = ?', $client_email);

$subquery = $select->getPart(Zend_Db_Select::WHERE);
$select ->reset(Zend_Db_Select::WHERE);
$select ->where('company_id = ?', $company_id)
        ->where(implode(' ',$subquery));

Ответ 3

Для Zend Framework версии 2 все немного отличается:

См. http://framework.zend.com/apidoc/2.2/classes/Zend.Db.Sql.Predicate.Predicate.html#nest

$table->select()
     ->where(['company_id'=> $company_id])
     ->nest
         ->where('client_email = ?', $client_email)
         ->or
         ->where('client_email_alt = ?', $client_email)
     ->unnest();

работает отлично и чувствует себя намного чище, чем методы ZF1.

Ответ 4

Вначале вы можете сгенерировать подзапрос, затем получить часть "WHERE" и вставить в основной запрос

$subquery = $db->select();
$subquery->orWhere('a>10');
$subquery->orWhere('b<20');
etc..

$subquery = $subquery->getPart(Zend_Db_Select::WHERE);
$select->where(implode(' ',$subquery));

Ответ 5

Мне нужно было комбинировать операторы AND/OR, но с предложениями OR, условно, добавляя их только в некоторых случаях. Это решение является адаптацией того, что я сделал, основываясь на небольших модификациях принятого ответа.

$sql = $table->select()
         ->where('company_id = ?', $company_id);

$orWhereClauses = [];
// We could add a conditional statement to add this statement
$orWhereClauses[] = $db->quoteInto('client_email = ?', $email1);
// Same applies to this statement
$orWhereClauses[] = $db->quoteInto('client_email_alt = ?', $email2);

$sql->where(implode(" OR ", $orWhereClauses));