Nested Select using Zend Db - php

I have a query like
select empl.idemp ,(select em.firstnm from tbl_employeemaster em where em.idemp = empl.approvedby) as approvedby from tbl_empleaveapplication empl
join tbl_employeemaster emp on empl.idemp = emp.idemp
join tbl_leavemaster lvm on empl.idleavemaster = lvm.idleavemaster
I need to use zend db to build this type of query

Here is how you can convert your string query into Zend_Db_Select
class Empleaveapplication extends Zend_Db_Table_Abstract
{
protected $_name = 'tbl_empleaveapplication';
}
$table = new Empleaveapplication();
// create sub query
$subSql = $table->select()
->setIntegrityCheck(false)
->from(array('em' => 'tbl_employeemaster'), array('firstnm'))
->where('idemp = empl.approvedby', '');
// main query
$sql = $table->select()
->setIntegrityCheck(false)
->from(array('empl' => 'tbl_empleaveapplication'), array('idemp', 'approvedby' => new Zend_Db_Expr('(' . $subSql . ')')))
->joinInner(array('emp' => 'tbl_employeemaster'), 'empl.idemp = emp.idemp', array())
->joinInner(array('lvm' => 'tbl_leavemaster'), 'empl.idleavemaster = lvm.idleavemaster', array());

Related

Zend Framework 2: how to get columns from joined tables?

I am using Zend Framework 2.4 with TableGateway and need to execute the following query:
SELECT products.title, student.firstname, orders.order_id,
orders.profile_id, orders.status
FROM student
INNER JOIN
(products
INNER JOIN orders ON products.product_id = orders.product_id)
ON student.student_id = orders.student_id
WHERE (((orders.profile_id)='.$id.'));
Here is what I am using:
$select = $this->tableGateway->getSql()->select();
$select->columns(array('*'))
->join('products', 'products.product_id = orders.product_id', array('title'))
->join('student', 'student.student_id = orders.student_id', array('first_name'))
->where(array('orders.profile_id' => $id));
$items = $this->tableGateway->selectWith($select);
return $items;
The problem is that $items does not contain the columns title or first_name. It only contains the columns from the orders table.
What do I need to do to get $items to contain the columns from the joined tables?
try to use an associative array
$select = $this->tableGateway->getSql()->select();
$select->columns(array('*'))
->join('products', 'products.product_id = orders.product_id', array('title' => 'product_title'))
->join('student', 'student.student_id = orders.student_id', array('first_name' => 'student_first_name'))
->where(array('orders.profile_id' => $id));
$items = $this->tableGateway->selectWith($select);
return $items;

Adding IF clause to zend framework 1 database table select object

Here is my sql:
SELECT id,`status`,IF(`status` = 'active', 'deleted','active') AS `status-use`
FROM categories
And here is my code: (ActionResourceModel is a Zend_Db_Table )
$dbTable = $this->getActionResourceModel();
$select = $dbTable->select();
$select->from($dbTable,$this->getQueryColumns());
$select->order($orderClause.' '.$orderSpec);
How do I add to my select object :
IF(`status` = 'active', 'deleted','active') AS `status-use`
Your select should look like:
$dbTable = $this->getActionResourceModel();
$select = $dbTable->select();
$select->from(
$dbTable,
array(
'status-use' => new Zend_Db_Expr("IF(`status` = 'active', 'deleted','active')"
)
);
You can extend from Zend_Db_Table and define a function that create this query. you could see Zend_Db_Table functions like join, from, etc for design your special class

How can I turn ZF ->joinLeft()s into a Subquery?

How would i convert below query to sub query?
I don't want to use JOINS I want to do same through sub query. i-e I need three subqueries out of the three joins. How it would be possible for below query ?
protected $_name = 'sale_package_features';
public function getAllSalePackageFeatures(){
$sql = $this->select()->setIntegrityCheck(false)
->from(array('spf' => $this->_name))
->joinLeft(array('sd' => 'sale_devices'),'sd.sale_device_id = spf.sale_device_id',array('sd.sale_device_name AS deviceName'))
->joinLeft(array('sp' => 'sale_packages'),'sp.sale_package_id = spf.sale_package_id',array('sp.sale_package_name AS packageName'))
->joinLeft(array('sf' => 'sale_features'),'sf.sale_feature_id = spf.sale_feature_id',array('sf.sale_feature_name AS featureName'))
->where('sf.parent_id != ?',0)
->order('spf.sale_package_feature_id ASC');
return $sql->query()->fetchAll();
}
Edited :
SELECT
`spf`.*, `sd`.`sale_device_name` AS `deviceName`,
`sp`.`sale_package_name` AS `packageName`,
`sf`.`sale_feature_name` AS `featureName`
FROM `sale_package_features` AS `spf`
LEFT JOIN `sale_devices` AS `sd`
ON sd.sale_device_id = spf.sale_device_id
LEFT JOIN `sale_packages` AS `sp`
ON sp.sale_package_id = spf.sale_package_id
LEFT JOIN `sale_features` AS `sf`
ON sf.sale_feature_id = spf.sale_feature_id
WHERE (sf.parent_id != 0)
ORDER BY `spf`.`sale_package_feature_id` ASC
You can use
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$subSelect = $dbAdapter
->select()
->from( 'tablename',
array(
'col1_alias' => 'column1_name',
'col2_alias' => 'column2_name',
))
->where('somefield = ?', $value_to_be_quoted);
$select = $dbAdapter
->select()
->from(array('sub_alias' => $subSelect ))
->where('otherfield = ?', $other_value_to_be_quoted);
$sql = $select->assemble();
$sql will contain
SELECT
sub_alias . *
FROM
(SELECT
tablename.column1_name AS col1_alias,
tablename.column2_name AS col2_alias
FROM
tablename
WHERE
(somefield = 'quoted_value')) AS sub_alias
WHERE
(otherfield = 'quoted_other_value')
If you need to use SELECT .. WHERE x IN (subselect) than go with
$select->where( 'column IN (?)', new Zend_Db_Expr($subselect->assemble()) );

LEFT JOIN Association returns unknown column

I am using PHPActiveRecord and CodeIgniter. I am trying to create a blog CMS and a blog has many categories and its referring to another table called blogrefs. So basically
blogs => blogrefs => blogcats
blogrefs is referring with blogs through blogrefs.blog_id
blogrefs is referring with blogcats through blogrefs.blogcat_id
function get_blogs($params = array()){
$CI =& get_instance();
$joins = 'LEFT JOIN blogrefs ON blogs.id = blogrefs.blog_id';
$joins .= 'LEFT JOIN blogcats ON blogrefs.blogcat_id = blogcats.id';
$category = (isset($params['category']))?$params['category']:'';
$keyword = (isset($params['keyword']))?$params['keyword']:'';
$status = (!isset($params['status']) || $params['status'] == '')?'':$params['status'];
$order_by = (isset($params['order_by']))?$params['order_by']:'created_on';
$direction = (isset($params['direction']))?$params['direction']:'DESC';
$limit = (isset($params['limit']))?$params['limit']:'';
$offset = (isset($params['offset']))?$params['offset']:'';
$st = '';
if($status == ''){
$st = '!';
}
if(!empty($category))
{
$conditions = array(
"((blogcats.id = ?) OR (blogcats.parent_id = ?))
AND blogs.status $st= ?
AND (blogs.title LIKE '%$keyword%' OR blogs.content LIKE '%$keyword%')",$category,$category,$status
);
}else{
$conditions = array(
"blogs.status $st= ?
AND (blogs.title LIKE '%$keyword%' OR blogs.content LIKE '%$keyword%')",$status
);
}
$result = Blog::find('all',array(
'include' => array('blogcat','blogref','user'),
'joins' => $joins,
'conditions' => $conditions,
'limit' => $limit,
'offset' => $offset,
'order' => "$order_by $direction",
'group' => 'blogs.id'
));
$count = Blog::find('all',array(
'conditions' => $conditions
));
$object = new stdClass;
$object->posts = $result;
$object->total = count($count);
return $object;
}
Everything works not only if i use
((blogcats.id = ?) OR (blogcats.parent_id = ?))
To get blogs from specific category. Any answers will be very much appreciated.
I don't find this very clear. Why not use a model and CI's Active Record Class? (http://ellislab.com/codeigniter/user-guide/database/active_record.html), like
$this->db->where('blogrefs.blogcat_id', $catid);
$this->db->join('blogrefs', 'blogs.id = blogrefs.blog_id');
...
Your error is a missing space at the end of where you define the first part of your join.
$joins = 'LEFT JOIN blogrefs ON blogs.id = blogrefs.blog_id';
$joins .= 'LEFT JOIN blogcats ON blogrefs.blogcat_id = blogcats.id';
evaluates to:
LEFT JOIN blogrefs ON blogs.id = blogrefs.blog_idLEFT JOIN blogcats ON blogrefs.blogcat_id = blogcats.id
You'll notice that the first join is screwed up by looking for a column named 'blog_idLEFT' and that the second JOIN will now be an inner join, not an outer left join.
I'd recommend either going with davedriesmans's suggestion, or finding someway to output the final mySQL queries you are generating. (Or both)

zend select query inside joinleft

How to write SELECT query inside JOIN LEFT in a Zend model?
for eg how to convert the following mysql query to zend model query
LEFT JOIN
(SELECT count(*) as game_count,topic_id,time as g_time from games_list WHERE type < 3 GROUP BY topic_id) t3
ON chapter_list.id=t3.topic_id
I want to add converted query with the following zend query and I need game_count from the above query with the following result.
$query = $this->select()
->setIntegrityCheck(false)
->from(array('a' => 'chapter_list'), array('subtopic_id as topic','id as topic_id','grade','chapter_no as chapter','if(file_status=1,1,0) as ppt)','CONCAT("http://mysite.com?t=",subtopic_id) as link'))
->joinLeft(array('b' => 'subject_list'), 'a.subject = b.subject_id', array());
return $this->fetchAll($query)->toArray();
Finally I got it,
$subquery1= $this->select()
->setIntegrityCheck(false)
->from('games_list', array('count(*) as game_count','topic_id','time as g_time'))
->where('type<?', 3)
->group('topic_id');
//main query
$query = $this->select()
->setIntegrityCheck(false)
->from(array('a' => 'chapter_list'), array('subtopic_id as topic','id as topic_id','grade','chapter_no as chapter','if(file_status=1,1,0) as ppt)','CONCAT("http://eskool.com/learn?t=",subtopic_id) as link'))
->joinLeft(array('b' => 'subject_list'), 'a.subject = b.subject_id', array())
->joinLeft(array('c' => $subquery1), 'a.id = c.topic_id', array('IFNULL(game_count,0)','g_time'))
return $this->fetchAll($query)->toArray();

Categories