Select Columns to return when joining a table with Zend\Db\Sql - zend-framework2

I just want to return one column (per.cd_acao), so I tried something like:
$select->from(array('act' => 'tb_acao'))
->join(array('per' => 'tb_perfil_acao'),
'per.cd_acao = act.cd_acao',
array('cd_acao'),
$select::JOIN_INNER
);
but this is producing a query string like:
SELECT "act".*, "per"."cd_acao" AS "cd_acao" FROM "tb_acao" AS "act" INNER JOIN "tb_perfil_acao" AS "per" ON "per"."cd_acao" = "act"."cd_acao" WHERE "per"."sq_perfil" = '89'
it is bringing all columns from the first table, when I want none. What am I missing here?
Update
summarizing: When I don't inform 'columns' in a select object, it defaults to return all columns to me. But when I'm joining, I don't want any columns to be returned by the first table.

An empty array will suffice
$select->from(array('act' => 'tb_acao'))
->columns(array())
->join(array('per' => 'tb_perfil_acao'),
'per.cd_acao = act.cd_acao',
array('cd_acao'),
$select::JOIN_INNER
);

Try with this query
use Zend\Db\Sql\Sql;
protected $tableGateway;
public $adapter;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
publice function getData(){
$adapter = $this->tableGateway->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('tb_acao')
->join('per'),
'per.cd_acao = act.cd_acao',
array('cd_acao'),
);
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
return $results;
}

Related

how to fit complex mysql query into zf2

i am unable to fit my query into zf2 query, i can fit simple join query but i can not write for more complex sub queries.
please help me to do this.
SELECT `created_date` FROM `salesmodule_discussed_topic` dt WHERE dt.`meeting_id` IN(
SELECT ma.`meeting_id` FROM `salesmodule_meeting_agent` ma WHERE ma.`agent_id`=30547
)
public function getLastmeetingdate() {
$select = new Select();
$select->from(array('dt' => 'salesmodule_discussed_topic'));
$select->columns(array('created_date'));
$select->where(array('ma.`agent_id` => 30547));
$resultSet = $this->tableGateway->selectWith($select);
return $resultSet->buffer();
}
The previous example is bad because has an sql injections. You need make a subquery using Select.
public function getLastmeetingdate() {
$subQuery = new Select();
$subQuery->from(array('ma' => 'salesmodule_meeting_agent'));
$subQuery->columns(array('meeting_id'));
$subQuery->where(array('ma.agent_id' => 30547));
$select = new Select();
$select->from(array('dt' => 'salesmodule_discussed_topic'));
$select->columns(array('created_date'));
$select->where->in('dt.meeting_id', $subQuery);
return $this->tableGateway->selectWith($select);
}
public function fetchAllSubQuery($id = '') {
$columns = array("*");
$where = "main_booking_id IN (SELECT
b1.`main_booking_id`
FROM
`booking_sector` b1
WHERE b1.`connected_booking_id` = '$id' OR b1.`main_booking_id` = '$id') ";
$resultSet = $this->tableGateway->select(function (Select $select) use ($where,$columns) {
$select->where($where);
$select->columns($columns);
});
$resultSet->buffer();
// $resultSet->next();
return $resultSet;
}

How to use having() in tableGateway in ZF2

How to use having() clause in ZF2?
There is almost no examples on the web how to prepare correct select object with having.
I have query like:
SELECT root_schema_id as `schema_id`
FROM `standard_specific_root_schemas`
WHERE `vehicle_id` IN (".implode(",",$vehiclesIds).")
GROUP BY `schema_id`, rootSubGroup_id HAVING count(*)=".$noOfVehicles
And I'm trying to run it in ZF2:
public function getVehicleWithinCommonRootSubgroupInSpecific($vehiclesIds)
{
$where = new Where();
$where->in('vehicle_id', $vehiclesIds);
$having = new Having('count(*) = '.count($vehiclesIds));
$rowset = $this->tableGateway->select(function (Select $select) use ($where, $having) {
$select
->where($where)
->having($having);
});
if (!$rowset) {
throw new \Exception("Could not find schemas for group $groupId");
}
return $rowset;
}
Of course that part in ZF2 is not finished yet as I wanted to check if it's working first.
I've tried few ways of providing params to having method but everything generates errors.
Help please, I'm desperate...
I cannot test your query, but can try and reproduce the query you need.
I adjusted the having to use ->expression() instead of a variable via the construct.
I also added the group statement.
To view the query I added a var_dump:
$where = new \Zend\Db\Sql\Where();
$where->in('vehicle_id', $vehiclesIds);
$having = new \Zend\Db\Sql\Having();
$having->expression('count(*) = ?', count($vehiclesIds));
$rowset = $this->tableGateway->select(function (\Zend\Db\Sql\Select $select) use ($where, $having) {
$select
->where($where)
->group(array('schema_id', 'rootSubGroup_id'))
->having($having);
var_dump( $select->getSqlString() );
});
Let me know if this helps.
To circumvent the error mentioned in the comments you would have to do something like below:
$sql = $this->tableGateway->getSql();
$select = $sql->select();
$where = new \Zend\Db\Sql\Where();
$where->in('vehicle_id', $vehiclesIds);
$having = new \Zend\Db\Sql\Having();
$having->expression('count(*) = ?', count($vehiclesIds));
$select
->where($where)
->group(array('schema_id', 'rootSubGroup_id'))
->having($having);
$preparedQuery = $sql->prepareStatementForSqlObject($select);
var_dump( $preparedQuery->getSql() );
However, if I'm right, the tableGateway does this for you so the error should go away once you start using the select to query the database.
Also, you can use the above to do that too, just replace this:
$preparedQuery = $sql->prepareStatementForSqlObject($select);
var_dump( $preparedQuery->getSql() );
With:
$this->tableGateway->selectWith($select);

Clauses OR Where in Zend framework 2

I'm new to ZF2.
How can I write a query like this?
SELECT * FROM users WHERE id = 1 AND status != 2
My code Model:
public function getUser($where = array())
{
$select = $this->sql->select();
$select->from(self::TABLE);
$select->where($where);
$select->order('name ASC');
return $statement->execute();
}
I am using: Zend\Db\Sql
Thanks.
Look at the docs here.
So $where can be a string or Closure, too.
Call it in your case like:
$user = $object->getUser('status != 2');
Oh, I missed the first condition:
$user = $object->getUser(array('id = 1', 'status != 2'));
EDIT:
You can for sure leave the = array() default value. I don't know why but I confused it with type hinting. (array $where)
public function getUser( where = array() ) {
$select = $this->sql->select();
$select->from(self::TABLE);
$select
->where->nest()
->equalTo( 'id' => where['id'] )
->or
->notEqualTo( 'status' => where['status'] )
->unnest();
$select->order('name ASC');
return $statement->execute();
}
use like this:
getUser( array(
'id' => 1,
'where' => 2,
) );

zf2 select columns from joined tables - how?

I feel like I must me missing something very simple. It's a very simple task, all I want to do is get something like:
SELECT * FROM lookup_items
JOIN lookup ON lookup_items.lookup_id = lookup.id
This returns all the columns for all the joined tables, in regular SQL. Here's my attempt in zf2:
$select = new Select();
$select->from('lookup_items');
$select->join('lookup', 'lookup_items.lookup_id = lookup.id');
The result set only includes the columns in 'lookup_items'. I've tried various ways to get the 'lookup' columns, including:
$select->columns(array('lookup_items.*', 'lookup.*'));
But they all just blow up. Surely there's a way to do this, and it's just so simple I'm missing it completely.
I thought a simple example would be avoid confusion, but here's more code:
class LookupItemsTable extends AbstractTableGateway
{
public function getList($resource)
{
$system_name = str_replace('*', '%', strtoupper($resource));
$joinTable = 'lookup';
$select = new Select();
$select->from($this->table);
$select->join($joinTable, "{$this->table}.lookup_id = {$joinTable}.id");
$where = array();
$where[] = "{$this->table}.enabled is true";
$where[] = "{$joinTable}.enabled is true";
$where[] = "UPPER({$joinTable}.system_name) ilike '{$system_name}'";
$select->where($where);
$sort[] = 'sort_order ASC';
$sort[] = 'value ASC';
$select->order($sort);
$rowset = $this->selectWith($select);
return $rowset;
}
}
Where:
$resource = $this->params()->fromRoute('resource', 'BUSINESS');
And $this->table is 'lookup_items'. Really all I want to do is get columns from both joined tables. I guess there's a zf2 way to just make a straight SQL statement without all the OO falderal, so I could just force it that way. But I'd rather work within the framework as much as possible.
Just change this line
$select->join('lookup', 'lookup_items.lookup_id = lookup.id');
to
$select->join('lookup', 'lookup_items.lookup_id = lookup.id', array('lookupcol1', 'lookupcol2');
Raj answer is the best one but it only works if you don't forget to add these fiels in your LookupItems model.
class LookupItems
{
// Your lookup_items fields here...
...
// And the added lookup fields here, the ones you add in the array
public $lookupcol1;
public $lookupcol2;
And in the exchangeArray method :
public function exchangeArray($data)
{
// .... your fields, and the new ones
$this->lookupcol1 = (! empty($data['lookupcol1'])) ? $data['lookupcol1'] : null;
$this->lookupcol2 = (! empty($data['lookupcol2'])) ? $data['lookupcol2'] : null;
}
I figured it out.
Added this:
$select->columns(array('*'));
And then this near the end:
$sql = new Sql($this->adapter);
$statement = $sql->prepareStatementForSqlObject($select);
$rowset = $statement->execute();
This returns the expected result, with the caveat that now my rows are returned as associative arrays instead of objects.
This is how you can create queries with join in zf2.
$resultSet = $this->select(function (Select $select) {
// omit the table name
//$select->from('foo');
$select->join('users', "users.id foo.createdby", 'firstname', '');
$select->order('id ASC');
// echo $select->getSqlString();// to print your query
});
$entities = array();
foreach ($resultSet as $row) {
$entity = new Entity\Foo();
$entity->setId($row->id)
->setFullname($row->fullname)
->setCaseid($row->caseid)
->setTestimonial($row->testimonial)
->setSortorder($row->sortorder)
->setActive($row->active)
->setCreated($row->created)
->setModified($row->modified)
->setFirstname($row->firstname)
->setCreatedby($row->createdby);
$entities[] = $entity;
}
return $entities;

How manage a VIEW with Doctrine 2?

I would like mapping a sql-view with Doctrine2.
This view is a TempTable containing some statistics that would show without rewriting the sql that generates the view
I try to map like a table, but updating schema drop the view and create a table
I try also with NativeSQL...
public function getMessages(\Project\Bundle\MyBundle\Entity\User $user) {
$rsm = new \Doctrine\ORM\Query\ResultSetMapping();
$rsm->addEntityResult('MessageCenter', 'v');
$rsm->addFieldResult('v', 'user_id', 'user_id');
$rsm->addFieldResult('v', 'tot', 'tot');
$rsm->addFieldResult('v', 'read', 'read');
$rsm->addFieldResult('v', 'to_read', 'to_read');
$rsm->addFieldResult('v', 'stored', 'stored');
$rsm->addFieldResult('v', 'spam', 'spam');
$q = "SELECT * FROM message_stats_view WHERE user_id = ?";
$rsm = new \Doctrine\ORM\Query\ResultSetMapping;
$query = $this->getEntityManager()->createNativeQuery($q, $rsm);
$query->setParameter(1, $user->getId());
echo $query->getSQL();
var_dump($query->execute());
exit;
}
I create the entity MessageCenter with getter and setter, but my output is:
SELECT * FROM message_stats_view WHERE user_id = ?
array
empty
(Answered by the OP in aq question edit. Transcribed to a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
I SOLVED!!!!
public function getCentroMessaggi(\Project\Bundle\MyBundle\Entity\User $user) {
$connection = $this->getEntityManager()->getConnection();
$q = "SELECT * FROM message_stats_view WHERE user_id = :id";
$stmt = $connection->executeQuery($q, array('id' => $user->getId()));
return $stmt->fetch();
}
This return an array. PERFECT!

Resources