Zend Framework 2 Zend\Db\Select how to join another Select - sql

How can I make a join with another Select Object? I need make a query like this
$select->join(array('alias' => $subSelect), 'on clause', 'array('*'), 'left');
Something like this was possible in ZF1.x.
In ZF2 first argument of join method is name of table or array with alias but i can't put there \Select. Even if i put here
$select->getSqlString($this->adapter->platform);
string is quoted, and query is not valid. Join doesn't add brackets too. It's really confusing.

Maybe this will help you. This is a working example I have in my TableGateway:
public function Profile($params)
{
$result = $this->select(function (Select $select) use ($params) {
$select
->columns(array(
'ipaddress_type',
'ipaddress',
'domain'
))
->join('product_hosting_profile', 'product_hosting_profile.productid = webaccount.productid', array(
'servers',
'services'
))
->where(array(
$this->adapter->getPlatform()->quoteIdentifierChain(array('webaccount', 'accountid')) . ' = ' . $this->adapter->getPlatform()->quoteValue($params['accountid']),
$this->adapter->getPlatform()->quoteIdentifierChain(array('webaccount', 'productid')) . ' = ' . $this->adapter->getPlatform()->quoteValue($params['productid']),
$this->adapter->getPlatform()->quoteIdentifierChain(array('webaccount', 'webaccountid')). ' = ' . $this->adapter->getPlatform()->quoteValue($params['webaccountid'])
))
->limit(1);
});
return $result->current();
}

$subSelect=new Select(array('A'=>new TableIdentifier('target','CAT')));
$subSelect->columns(array('fk_w','TI'=>'id','mtarget_f'=>new Expression('sum(F)'),
'mcost'=>new Expression('round(sum(F*D.mcost),2)')))
->join(array('B'=>new TableIdentifier('item','CAT')),'B.id=A.fk_w',
array())
->join(array('D'=>new TableIdentifier('rate','CAT')),'A.dat=D.year and D.fk_c=B.CCODE and D.fk_b=A.fk_b',
array())
->where->equalTo('Year', $year);
$select=new Select(array('A'=>new TableIdentifier('item','CAT')));
$select->columns(array('WID'=>'id','AID'=>'AID',
'item'=>'ITEM_ID','Wtitle'=>'WTITLE'))
->join(array('B'=>new TableIdentifier('cn','CAT')),'B.id=A.CCODE',
array('Ct'=>'name'))
->join(array('S'=>$subSelect),'S.fk_w=A.id',array('Mtarget'=>'mcost',
'MTarget'=>'m_target',
'TID'),'left');

Related

Yii left join query

I want to execute the below sql query using Yii framework and need help on this.
SQL query
SELECT t.*, LP.name AS lp_name FROM `user` AS `t` LEFT JOIN `level_profiles` AS `LP` ON t.prof_i = LP.id WHERE t.bld_i IN (17)
So, i tried the below steps.
$usql = 't.bld_i IN (17)';
$criteria1 = new CDbCriteria;
$criteria1->select = 't.*, LP.*';
$criteria1->join = ' LEFT JOIN `level_profiles` AS `LP` ON t.prof_i = LP.id';
$criteria1->addCondition($usql);
$criteria1->order = 't.prof_i';
$result = User::model()->findAll($criteria1);
The above step is not allowing me to access the value from 'level_profiles' table.
Then, i tried to execute:
$usql = 't.bld_i IN (17)';
$result = User::model()->with('level_profiles', array(
'level_profiles'=>array(
'select'=>'name',
'joinType'=>'LEFT JOIN',
'condition'=>'level_profiles.id="prof_i"',
),
))->findAll($usql);
This is returning an error 'Relation "level_profiles" is not defined in active record class "User". '
I know this could be executed using the below method.
Yii::app()->db->createCommand('SELECT query')->queryAll();
But i dont want to use the above.
I am a beginner with Yii and tried to look into the forums. But, i am getting confused how to execute the query using "User::model()" approach .
class User extends CActiveRecord
{
......
public function relations()
{
return array(
'level_porfile_relation'=>array(self::BELONGS_TO, 'Level_Profiles_Modelname', 'prof_i'),
);
}
and your query will be:
$result = User::model()->with('level_porfile_relation')->findAll($usql);

Magento resource: custom selects with OR in where (select orders by status)

I'm building a custom module and i'm trying get all orders with specific status:
$canceledQuery = Mage::getSingleton('core/resource')->getConnection('core_read')->select()
->from('mage_sales_flat_order', 'entity_id')
->where('status = ?', 'canceled');
This works very well. But now i'm trying use OR in where, without success.
I have been try this:
$whereCanceled = array();
foreach ($_status as $statusCode => $value) {
$whereCanceled[] = sprintf('%s=:%s', 'status', $statusCode);
}
$ordersQuery = Mage::getSingleton('core/resource')->getConnection('core_read')->select()
->from('mage_sales_flat_order', 'entity_id')
->where(implode(' OR ', $whereCanceled));
So, I don't know how use OR right in this case. I found no use for this with OR. Any idea?
instead of implode use join. magento use join itself.
->where(join(' OR ', $orWhere));//$orWhere array of condition
you can see in below function magento use join for OR condition in where clause
public function getSystemConfigByPathsAndTemplateId($paths, $templateId)
{
$orWhere = array();
$pathesCounter = 1;
$bind = array();
foreach ($paths as $path) {
$pathAlias = 'path_' . $pathesCounter;
$orWhere[] = 'path = :' . $pathAlias;
$bind[$pathAlias] = $path;
$pathesCounter++;
}
$bind['template_id'] = $templateId;
$select = $this->_getReadAdapter()->select()
->from($this->getTable('core/config_data'), array('scope', 'scope_id', 'path'))
->where('value LIKE :template_id')
->where(join(' OR ', $orWhere));
return $this->_getReadAdapter()->fetchAll($select, $bind);
}
for more reference open file located at [magento]/app/code/core/Mage/Core/Model/Resource/Email/Template.php
Hope this help you

codeigniter change complex query into active record

I have a codeigniter app.
My active record syntax works perfectly and is:
function get_as_09($q){
$this->db->select('m3');
$this->db->where('ProductCode', $q);
$query = $this->db->get('ProductList');
if($query->num_rows > 0){
foreach ($query->result_array() as $row){
$row_set[] = htmlentities(stripslashes($row['m3'])); //build an array
}
return $row_set;
}
}
This is effectively
select 'm3' from 'ProductList' where ProductCode='$1'
What I need to do is convert the below query into an active record type query and return it to the controller as per above active record syntax:
select length from
(SELECT
[Length]
,CONCAT(([width]*1000),([thickness]*1000),REPLACE([ProductCode],concat(([width]*1000),([thickness]*1000),REPLACE((convert(varchar,convert(decimal(8,1),length))),'.','')),'')) as options
FROM [dbo].[dbo].[ProductList]) as p
where options='25100cr' order by length
I picture something like below but this does not work.
$this->db->select(length);
$this->db->from(SELECT [Length],CONCAT(([width]*1000),([thickness]*1000),REPLACE[ProductCode],concat(([width]*1000),([thickness]*1000),REPLACE((convert(varchar,convert(decimal(8,1),length))),'.','')),'')) as options
FROM [dbo].[dbo].[ProductList]);
$this->db->where(options, $q);
$this->db->order(length, desc);
Help appreciated as always. Thanks again.
You can use sub query way of codeigniter to do this for this purpose you will have to hack codeigniter. like this
Go to system/database/DB_active_rec.php Remove public or protected keyword from these functions
public function _compile_select($select_override = FALSE)
public function _reset_select()
Now subquery writing in available And now here is your query with active record
$select = array(
'Length'
'CONCAT(([width]*1000)',
'thickness * 1000',
'REPLACE(ProductCode, concat((width*1000),(thickness*1000),REPLACE((convert(varchar,convert(decimal(8,1),length))),'.','')),'')) as options'
);
$this->db->select($select);
$this->db->from('ProductList');
$Subquery = $this->db->_compile_select();
$this->db->_reset_select();
$this->db->select('length');
$this->db->from("($Subquery)");
$this->db->where('options','25100cr');
$this->db->order_by('length');
And the thing is done. Cheers!!!
Note : While using sub queries you must use
$this->db->from('myTable')
instead of
$this->db->get('myTable')
which runs the query.
Source

opencart getcategories function goes into infinite loop

I have an opencart shop with around 1300 categories and i'm not able to insert a new category or edit the existing category. I have installed pagination function, but it speeds up only category view. i did some debugging and found that the below function goes into an infinite loop once i click insert or edit inside the admin panel. Can anyone help me how to fix this
public function getCategories($parent_id = 0) {
$category_data = $this->cache->get('category.' . (int)$this->config->get('config_language_id') . '.' . (int)$parent_id);
if (!$category_data) {
$category_data = array();
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category c LEFT JOIN " . DB_PREFIX . "category_description cd ON (c.category_id = cd.category_id) WHERE c.parent_id = '" . (int)$parent_id . "' AND cd.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY c.sort_order, cd.name ASC");
foreach ($query->rows as $result) {
$category_data[] = array(
'category_id' => $result['category_id'],
'name' => $this->getPath($result['category_id'], $this->config->get('config_language_id')),
'status' => $result['status'],
'sort_order' => $result['sort_order']
);
$category_data = array_merge($category_data, $this->getCategories($result['category_id']));
}
$this->cache->set('category.' . (int)$this->config->get('config_language_id') . '.' . (int)$parent_id, $category_data);
}
return $category_data;
}
First Solution:
Do you also have Category Descriptions in database? If so, these so many descriptions being loaded by MySQL may be making burden over server. Try optimize the Query, select only required columns, you may change query as under:
$query = $this->db->query("SELECT c.category_id, cd.name FROM ...
Second Solution
You can do one more debug trick which once solved my problem. Add an echo statement:
echo $result['name'];
$category_data = array_merge($category_data, $this->getCategories($result['category_id']));` `
This way you'll get to know the exact location of the category where process gets hanged. There may be some problem with that particular category only.
Third Solution
Try changing
'name' => $this->getPath($result['category_id'], $this->config->get('config_language_id')),
To:
'name' => $result['name'],
Hope this helps.
I have a current but not permanent solution that worked for me... I dont know whether it's the right way to do, but it works for me.I changed the query to this
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category c ORDER BY c.parent_id,c.sort_order");
And commented off
//$category_data = array_merge($category_data, $this->getCategories($result['category_id']));
This currently works for me, but i don't know whether it's the correct way or not. Thanks for the quick help everyone.

How to get particular column in zend using Left join

I am new to zend framework,
Following is the plain mysql query which takes particular column from table,
SELECT jobs_users.id,jobs_users.first_name from jobs_users left join friends on jobs_users.id=friends.friend_id where friends.member_id=29
I tried with zend to implement the above query like below,
public function getFriendsProfileList($id){
$db = Zend_Db_Table::getDefaultAdapter();
$select = $db->select();
$select->from('jobs_users')
->joinLeft(
'friends',
'jobs_users.id=friends.friend_id',
array('jobs_users.id','jobs_users.first_name','jobs_users.last_name','jobs_users.photo')
)
->where("friends.member_id = ?", $id);
$result = $db->fetchAll($select);
return $result;
}
Here i got result with all column name , not with exact column name which i have given in query.
Kindly help me on this.
Use this instead:
$select->from('jobs_users', array('jobs_users.id','jobs_users.first_name','jobs_users.last_name','jobs_users.photo'))
->joinLeft('friends', 'jobs_users.id=friends.friend_id')
->where("friends.member_id = ?", '20');
You may also try this:
$select = $db->select();
$select->setIntegrityCheck(false);
$select->joinLeft('jobs_users','',array('jobs_users.id','jobs_users.first_name','jobs_users.last_name','jobs_users.photo'));
$select->joinLeft('friends','jobs_users.id=friends.friend_id', array());
$select->where("friends.member_id = ?", $id);
$result = $db->fetchAll($select);
return $result;