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

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;

Related

How to write sql query in yii2

I have a raw sql query which i run using yii2 Yii::$app->db->createCommand() but then i wonder i how i can use yii's method of writing queries to actualize the same thing.
$m = "SELECT p.basic_plan_amt AS basic,p.premium_plan_amt AS premium,p.daju_plan_amt AS daju,c.name
AS country FROM price p LEFT JOIN country c ON p.country_id = c.id WHERE p.country_id = " .$country_id;
though the above query works well and provide expected result, but then how can i write the same query using the below format
$model = \backend\models\Price::find()->select([p.basic_plan_amt AS basic,p.premium_plan_amt AS
premium,p.daju_plan_amt AS daju,c.name
AS country])->where(['country_id' => $country_id])->all();
Below are the examples of query in yii hope it will help you More reference
Relation Model
$model = User::find()
->with('comments')
->all();
foreach ($model as $user) {
// get data from relation model
$comments = $user->comments;
......
foreach($comments as $comment){
........
}
}
joinWith()
Sample 1:
$model = User::find()
->joinWith('comments')
->all();
Sample 2:
$model = User::find()
->joinWith('comments')
->orderBy('tbl_comments_id.id, tbl_user.id')
->all();
innerJoinWith()
$model = User::find()
->innerJoinWith('comments', false)
->all();
// equivalent to the above
$model = User::find()
->joinWith('comments', false, 'INNER JOIN')
->all();
Join()
JOIN_TYPE = INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN etc
Syntax
$query = new Query;
$query ->select(['SELECT COLUMNS'])
->from('TABLE_NAME_1')
->join( 'JOIN_TYPE',
'TABLE_NAME_2',
'TABLE_NAME_2.COLUMN =TABLE_NAME_1.COLUMN'
);
$command = $query->createCommand();
$data = $command->queryAll();
Sample 1:
$query = new Query;
$query ->select([
'tbl_user.username AS name',
'tbl_category.categoryname as Category',
'tbl_document.documentname']
)
->from('tbl_user')
->join('LEFT OUTER JOIN', 'tbl_category',
'tbl_category.createdby =tbl_user.userid')
->join('LEFT OUTER JOIN', 'tbl_document',
'tbl_category.cid =tbl_document.did')
->LIMIT(5) ;
$command = $query->createCommand();
$data = $command->queryAll();
Output Query
SELECT `tbl_user`.`username` AS `name`, `tbl_category`.`categoryname` AS `Category`
FROM `tbl_user`
LEFT OUTER JOIN `tbl_category` ON tbl_category.createdby =tbl_user.userid
LEFT OUTER JOIN `tbl_document` ON tbl_category.cid =tbl_document.did
LIMIT 5
leftJoin()
Sample 1:
$query = new Query;
$query ->select(['tbl_user.username AS name', 'tbl_category.type as Category'])
->from('tbl_user')
->leftJoin('tbl_category', 'tbl_category.createdby = tbl_user.userid')
->limit(2);
$command = $query->createCommand();
$data = $command->queryAll();
Output Query
SELECT `tbl_user`.`username` AS `name`, `tbl_category`.`type` AS `Category`
FROM `tbl_user`
LEFT JOIN `tbl_category` ON tbl_category.createdby = tbl_user.useridd
LIMIT 2
use createcommand() method:
use yii\db\Query();
$connection = \Yii::$app->db;
$query = new Query;
$insql = $connection->createCommand("SELECT* FROM inventory );
$result=$insql->queryAll();
the above method list all data from the inventory table.

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();

How to INNER JOIN 3 tables using CodeIgniter

Can someone Tell me how to join 3 table with php?
Example
SELECT FROM table1, table2,table on INNERJOIN -------------------
let I have 3 table.(question table ,answer table and category table)
Here is example form my webpage.
Time remaining 30 minutes(I will get "30 minutes" form Category table)
1. Question (from question table)
2. answer (from answer table)
I don't know how to join 3 table.
it should be like that,
$this->db->select('*');
$this->db->from('table1');
$this->db->join('table2', 'table1.id = table2.id');
$this->db->join('table3', 'table1.id = table3.id');
$query = $this->db->get();
as per CodeIgniters active record framework
I believe that using CodeIgniters active record framework that you would just use two join statements one after the other.
eg:
$this->db->select('*');
$this->db->from('table1');
$this->db->join('table1', 'table1.id = table2.id');
$this->db->join('table1', 'table1.id = table3.id');
$query = $this->db->get();
Give that a try and see how it goes.
I created a function to get an array with the values ​​for the fields and to join. This goes in the model:
public function GetDataWhereExtenseJoin($table,$fields,$data) {
//pega os campos passados para o select
foreach($fields as $coll => $value){
$this->db->select($value);
}
//pega a tabela
$this->db->from($table);
//pega os campos do join
foreach($data as $coll => $value){
$this->db->join($coll, $value);
}
//obtem os valores
$query = $this->db->get();
//retorna o resultado
return $query->result();
}
This goes in the controller:
$data_field = array(
'NameProduct' => 'product.IdProduct',
'IdProduct' => 'product.NameProduct',
'NameCategory' => 'category.NameCategory',
'IdCategory' => 'category.IdCategory'
);
$data_join = array
( 'product' => 'product_category.IdProduct = product.IdProduct',
'category' => 'product_category.IdCategory = category.IdCategory',
'product' => 'product_category.IdProduct = product.IdProduct'
);
$product_category = $this->mmain->GetDataWhereExtenseJoin('product_category', $data_field, $data_join);
result:
echo '<pre>';
print_r($product_category);
die;
I think in CodeIgniter the best to use ActiveRecord as wrote above.
One more thing: you can use method chaining in AR:
$this->db->select('*')->from('table1')->join('table2','table1.id=table2.id')->...
$this->db->select('*');
$this->db->from('table1');
$this->db->join('table2', 'table1.id = table2.id','JOIN Type');
$this->db->join('table3', 'table1.id = table3.id');
$query = $this->db->get();
this will give you result from table1,table2,table3 and you can use any type of join in the third variable of $this->db->join() function such as inner,left, right etc.
For executing pure SQL statements (I Don't Know About the FRAMEWORK- CodeIGNITER!!!)
you can use SUB QUERY!
The Syntax Would be as follows
SELECT t1.id
FROM example t1 INNER JOIN
(select id from (example2 t1 join example3 t2 on t1.id = t2.id)) as t2 ON t1.id = t2.id;
Hope you Get My Point!
$this->db->select('*');
$this->db->from('table1');
$this->db->join('table2', 'table1.id = table2.id', 'inner');
$this->db->join('table3', 'table1.id = table3.id', 'inner');
$this->db->where("table1", $id );
$query = $this->db->get();
Where you can specify which id should be viewed or select in specific table. You can also select which join portion either left, right, outer, inner, left outer, and right outer on the third parameter of join method.
you can modiv your coding like this
$this->db->select('a.nik,b.nama,a.inv,c.cekin,c.cekout,a.tunai,a.nontunai,a.id');
$this->db->select('DATEDIFF (c.cekout, c.cekin) as lama');
$this->db->select('(DATEDIFF (c.cekout, c.cekin)*c.total) as tagihan');
$this->db->from('bayar as a');
$this->db->join('pelanggan as b', 'a.nik = b.nik');
$this->db->join('pesankamar_h as c', 'a.inv = c.id');
$this->db->where('a.user_id',$id);
$query = $this->db->get();
return $query->result();
i hope can be resolve your SQL
function fetch_comments($ticket_id){
$this->db->select('tbl_tickets_replies.comments,
tbl_users.username,tbl_roles.role_name');
$this->db->where('tbl_tickets_replies.ticket_id',$ticket_id);
$this->db->join('tbl_users','tbl_users.id = tbl_tickets_replies.user_id');
$this->db->join('tbl_roles','tbl_roles.role_id=tbl_tickets_replies.role_id');
return $this->db->get('tbl_tickets_replies');
}

Categories