Zend Framework 2 Sql Select with OR and AND
Asked Answered
R

2

9

I want to make this query using Zend\Db\Sql\Select:

SELECT table1.* FROM table1 
    INNER JOIN table2 ON table1.columnA = table2.columnB 
    INNER JOIN table3 ON table1.columnC = table3.columnD

WHERE (table2.column2 = 2 or table3.column3 = 3) and table1.column1 = 1

ORDER BY table1.columnE ASC LIMIT 1

I have this code so far:

/*@var $db Adapter */
$db = $this->getServiceLocator()->get('db');
$sql = new Sql($db);
$select = $sql->select();

$select->from('table1');
$select->join('table2','table1.columnA = table2.columnB',array());
$select->join('table3','table1.columnC = table3.columnD',array());

$select->where(array('table2.column2' => 2, 'table2.column3' => 3), Predicate\PredicateSet::OP_OR);

$select->where(array('table1.column1' => 1),Predicate\PredicateSet::OP_AND);

$select->order('table1.columnE ASC');
$select->limit(1);

$statement = $sql->prepareStatementForSqlObject($select);
$resultSet = $statement->execute();

But doesn't works, because produce this one (without the "(" and ")" for the OR):

SELECT table1.* FROM table1 
    INNER JOIN table2 ON table1.columnA = table2.columnB 
    INNER JOIN table3 ON table1.columnC = table3.columnD

WHERE table2.column2 = 2 or table3.column3 = 3 and table1.column1 = 1

ORDER BY table1.columnE ASC LIMIT 1

What can I do?

Recusancy answered 21/6, 2013 at 18:39 Comment(0)
M
35

from the top of the head using Where fluent interface:

$select->where
       ->nest
           ->equalTo('table2.column2', 2)
           ->or
           ->equalTo('table2.column3', 3)
       ->unnest
       ->and
       ->equalTo('table1.column1', 1);
Mia answered 22/6, 2013 at 5:43 Comment(3)
Thanks, I used the creation of "$where = new \Zend\Db\Sql\Where();" but this works fine too.Recusancy
@gsc-leticia that example will override any conditions already inplace, as $select->where($where) completely replaces Where object. Also unnecessary creation of extra object is a tiniest bit but perf hit.Mia
You are right, all works fine and this solution is more straightforwardRecusancy
M
6

I would do something like:

$where = new \Zend\Db\Sql\Where();

$where
    ->nest()
    ->equalTo('table2.column2', 2)
    ->or
    ->equalTo('table2.column3', 3)
    ->unnest()
    ->and
    ->equalTo('table1.column1', 1);
$select->where($where)

Just because this way your $select keep being an implementation of Zend\Db\Sql\SqlInterface while doing

$select->where
   ->nest

will return an instance of a Zend Sql operator. Which is not bad but then you can't just do

$statement = $sql->prepareStatementForSqlObject($select);
$resultSet = $statement->execute();
Microprint answered 22/6, 2013 at 10:58 Comment(1)
BTW using the other solution I could use: $sql->prepareStatementForSqlObject($select); and $resultSet = $statement->execute(); without problem.Recusancy

© 2022 - 2024 — McMap. All rights reserved.