Zend Framework 2: sql subquery - php

In ZF1 it worked like this:
$selectColumns = array(
'*',
'orders_total' => "(".$db->select()->from("orders", array("COUNT(*)"))->where("orders.parent_id=mytable.id").")",
);
$select = $db->select()->from('mytable', $selectColumns);
How to do this in the ZF2? Thanks.

Please try this.
$sql = new Sql($this->_adapter);
$mainSelect = $sql->select()->from('mytable');
$subQry = $sql->select()
->from('orders')
->columns(array('orderCount' => new \Zend\Db\Sql\Expression('COUNT(orders.id)')));
$mainSelect->columns(
array(
'id',
'orders_total' => new \Zend\Db\Sql\Expression('?', array($subQry)),
)
);
$statement = $sql->prepareStatementForSqlObject($mainSelect);
$comments = $statement->execute();
$resultSet = new ResultSet();
$resultSet->initialize($comments);
return $resultSet->toArray();
Link: ZF2 - subqueries

You can try this:
// Make your query here using the builder if you wish,
// but we will need to convert to string for the Expression
$sub = new Select('orders');
$sub->columns(array(new Expression('COUNT(*) as total')))
->where(array('id' => 4))
;
// You could just create an expression..
$subquery = new \Zend\Db\Sql\Expression("({$sub->getSqlString()})");
$select = new \Zend\Db\Sql\select('tablename'); // this is inside a
$select->columns(array('*', 'orders_total' => $subquery));
the output will be something like this:
SELECT
.*,
(SELECT COUNT(*) as total FROM "orders" WHERE "id" = '4') AS orders_total
FROM tablename
I haven't figured out a nice way of using the query builder to perform these kind of queries without having to use raw queries.

Without any more info you could try:
$selectColumns = array(
'*',
'orders_total' => "(".$db->select()->from("orders", array("COUNT(*)"))->where("orders.parent_id", "mytable.id").")",
);
$select = $db->select()->from('mytable', $selectColumns);
You will need to add at top with the use statements:
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Where;

You can try restructuring your SQL to something like:
SELECT
*,
SUM(IF(O.parent_id IS NULL, 0, 1)) AS orders_total
FROM mytable
LEFT JOIN orders O ON mytable.id = O.parent_id
Which you can represent using Zend Framework 2 as:
$select = new Select('mytable');
$select->columns(array(
'*',
'orders_total' => new Expression("SUM(IF(O.parent_id IS NULL, 0, 1))")
));
$select->join(array('O', 'orders'),
"mytable.id = O.parent_id",
Select::JOIN_LEFT);
$select->group(array('mytable.id'));
$result = $dbh->selectWith($select);
Assuming $dbh is your database adapter.

Related

Zend Framework 2 join the same table multiple times using alias

I'm struggling to implement multiple left JOINs into ZF2. I've got first one working, but when I add another one, it doesn't work.
This is the working SQL query which I should implement into zf2:
SELECT
ac.ctr_id AS ctr_id,
ac.ctr_no AS ctr_no,
ac.ctr_marketer AS marketer,
ac.ctr_manager AS manager,
ac.ctr_recruiter AS recruiter,
l1.emp_realname AS marketer,
l2.emp_realname AS co_recruiter_manager,
l3.emp_realname AS recruiter
FROM
allcontracts AS ac
JOIN
lstemployees AS le ON ac.ctr_recruiter = le.emp_id
LEFT JOIN
lstemployees AS l2 ON ac.ctr_manager = l2.emp_id
LEFT JOIN
lstemployees AS l3 ON ac.ctr_recruiter = l3.emp_id
LEFT JOIN
lstemployees AS l1 ON ac.ctr_marketer = l1.emp_id
from my model:
.....
$where = new Where();
$this->table='allcontracts';
$select = new Select($this->table);
$select->columns(array('*')); // TODO add columns from allcontracts table
// This one works
$select->join('lstemployees', 'allcontracts.ctr_recruiter = lstemployees.emp_id');
// When I add this one below it doesn't work
$select->join(array('l2' => 'lstemployees'), 'allcontracts.ctr_manager = l2.emp_id', array('*'), 'left');
$where->like('ctr_no', '%LT');
if($id!='' && $id > 0)
$where->equalTo('ctr_id', $id);
$select->where($where);
$resultSet = $this->selectWith($select);
......
Any idea?
Here is what I propose:
<?php
use Zend\Db\Sql\Select;
$select = new Select();
$select->columns([Select::SQL_STAR])
->from(['ac' => 'allcontracts '])
->join(['le' => 'lstemployees'], 'ac.ctr_recruiter = le.emp_id', [])
->join(['l1' => 'lstemployees'], 'ac.ctr_marketer = l1.emp_id', ['marketer' => 'emp_realname'], Select::JOIN_LEFT)
->join(['l2' => 'lstemployees'], 'ac.ctr_manager = l2.emp_id', ['co_recruiter_manager' => 'emp_realname'], Select::JOIN_LEFT)
->join(['l3' => 'lstemployees'], 'ac.ctr_recruiter = l3.emp_id', ['recruiter' => 'emp_realname'], Select::JOIN_LEFT);
// to debug your query
die($select->getSqlString($dbAdapter->getPlatform()));
// if you haven't $dbAdapter, replace by null but the result will be quoted.

ZF2 Inner Join on other timestamp

ZF2 Inner Join on other timestamp
Hello everybody, I would like to detect poitive edges in da Database with Zend Framework 2 (ZF2).
In mySQL it works with this command:
SELECT Ta1.datetime, Ta1.SensorId_47, Ta0.SensorId_47
FROM data_newobjects Ta1
INNER JOIN data_newobjects Ta0
ON Ta1.datetime = Ta0.datetime + SECOND(10)
WHERE (Ta1.SensorId_47 LIKE "1%" AND Ta0.SensorId_47 LIKE "0%");
But how can i join on the next timestamp like here the "+ SECOND(10)" in ZF2?
It works, if I join on the same timestamp in ZF2:
$sm = $this->getServiceLocator();
$sql =new Sql($sm->get('adapter_rohdata'));
$exp_Text = "`Ta_1`.`datetime` AS `summe`";
$select = $sql->select();
$select->columns(array(new Expression($exp_Text)));
$select->from(array('Ta_1' => 'data_newObjects'));
$select->join(array('Ta_0' => 'data_newObjects'), 'Ta_1.datetime=Ta_0.datetime', array(), \Zend\Db\Sql\Select::JOIN_INNER);
$select->where->like('Ta_0.SensorId_47', "0%");
$select->where->like('Ta_1.SensorId_47', "1%");
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
But I didn't find a solution, for the "next" timestamp, like it worked in mySQL for instance with "Ta1.datetime = Ta0.datetime + SECOND(10)"
Thanks for help... I really searched for help, and tryed a lot...
Got the solution from this post:
$select->join(
array('Ta_0' => 'data_newObjects'),
new \Zend\Db\Sql\Expression('Ta_1.datetime = Ta_0.datetime + SECOND(10)'),
array()
);

Zend framework sub query for update and select

I want to select all prices to show and next I want to update all price. I can write sub query in MySQL but how Can I do this in zend framework query style?
MySQL query is
SELECT price FROM mag1.catalog_product_option_type_price where option_type_id in
(SELECT option_type_id FROM mag1.catalog_product_option_type_value where option_id in
(SELECT option_id FROM mag1.catalog_product_option where product_id= 11));
To write your query exactly :
$select1 = new Select();
$select1->from('catalog_product_option')
->columns('option_id')
->where(array('product_id' => 11));
$where2 = new Where();
$select2 = new Select();
$select2->from('catalog_product_option_type_value')
->columns('option_type_id')
->where($where2->in('option_id', $select1);
$where = new Where();
$select = new Select();
$select->from('catalog_product_option_type_price')
->columns('price')
->where($where->in('option_type_id', $select2);
But why not try
$select = new Select();
$select->from(array('p' => 'catalog_product_option_type_price'))
->join(array('v' => 'catalog_product_option_type_value'), 'p.option_type_id = v.option_type_id', array())
->join(array('o' => 'catalog_product_option'), 'v.option_id = o.option_id', array())
->columns('price')
->where(array('o.product_id' => 11));
This should give the same result.

convert sql query to zend query

SELECT uls.prod_id,um.prod_image,um.prodname,SUM(msm.points)
FROM tbl_prod_selection AS uls
INNER JOIN tbl_prod_master AS um ON um.prod_id = uls.prod_id
INNER JOIN tbl_admin_prod_selection AS als ON als.user_id = uls.user_id
INNER JOIN tbl_prod_statistics_master AS msm ON (msm.user_id = uls.user_id AND msm.barcode_id = als.barcode_id)
WHERE uls.location_id = "18" AND uls.prod_code = "FLB"
GROUP BY uls.user_id;
can any one help to write zend query for this.
Thanks in Advance.
If you're using Zend_Db_Table, then you can assemble Zend_Db_Table_Select like below:
$select = $model->select()
->setIntegrityCheck(false)
->from(array('uls' => 'tbl_prod_selection'), array(
'uls.prod_id',
'um.prod_image',
'um.prodname',
'sum' => new Zend_Db_Expr('SUM(msm.points)'),
))
->join(array('um' => 'tbl_prod_master'), 'um.prod_id = uls.prod_id', array())
->join(array('als' => 'tbl_admin_prod_selection'), 'als.user_id = uls.user_id', array())
->join(array('msm' => 'tbl_prod_statistics_master'), 'msm.user_id = uls.user_id AND msm.barcode_id = als.barcode_id', array())
->where('uls.location_id = ?', '18')
->where('uls.prod_code = ?', 'FLB')
->group('uls.user_id');

Zend Database Mutli table "Select" via Join

Using Zend DB. I am trying to figure out how to write this query using the DB Class.
select
org.orgid
org.role
user.userid
user.firstname
from orgTable org
join userTable user on org.userid = user.userid
where org.orgid = 'generated-id'
from the documents I understand or think I understand how to do it with one definition using an AS like condition, but even then Im still not sure. Eventually this will branch out into a multi table join, based on cross table conditions so not sure how to achieve this to begin with.
I think this is what are you looking for
$db = Zend_Db::factory( ...options... );
$select = $db->select()
->from(array('org' => 'orgTable'),
array(
'orgid' => 'org.orgid',
'role' =>'org.role',
'userid' =>'user.userid',
'firstname' =>'user.firstname'
))
->join(array('user' => 'userTable'),
'org.userid = user.userid',array())
->where('org.orgid = ?',$generated_id);
Here is a Zend_Db_Select that returns the result you are looking for.
$select = $db->select()
->from(array('org' => 'orgTable'), array('orgid', 'role'))
->join(array('user' => 'userTable'), 'org.userid = user.userid', array('userid', 'firstname'))
->where('org.orgid = ?', 'generated-id');
You can use the array notation for table names to get the aliased names in the query.
Hope that helps.
In zend framework 2 , the following code helps you what are you looking for
$generated_id = 1 ;
$select = new \Zend\Db\Sql\Select( array('org' =>'orgTable'));
$select->columns(array('orgid','role') )
->join( array('user' => 'userTable'),
'org.userid = user.userid',
array('userid','firstname')
)->where( array('org.orgid' => $generated_id ) );
if your adapter platform is mysql, then for printing sql
$mysqlPlatform = new \Zend\Db\Adapter\Platform\Mysql();
echo $select->getSqlString( $mysqlPlatform );
which print sql as
SELECT
`org`.`orgid` AS `orgid`,
`org`.`role` AS `role`,
`user`.`userid` AS `userid`,
`user`.`firstname` AS `firstname`
FROM
`orgTable` AS `org`
INNER JOIN `userTable` AS `user`
ON `org`.`userid` = `user`.`userid`
WHERE
`org`.`orgid` = '1'

Categories