doctrin2 zf2 native sql joined table - php

I use this code to execute native sql query in zf2 application with doctrine2.
I use this code
$rsm = new ResultSetMapping();
$rsm->addEntityResult('Admin\Entity\SkillsExperience', 'skexp');
$rsm->addFieldResult('skexp', 'id', 'id');
$rsm->addFieldResult('skexp', 'idExperience', 'id_experience');
$rsm->addFieldResult('skexp', 'idSkillsDetails', 'id_skills_details');
$rsm->addJoinedEntityResult('Admin\Entity\SkillsDetails', 'skd','skexp','idSkillsDetails');
$rsm->addFieldResult('skd','description','description');
$rsm->addFieldResult('skd','idSkill','id_skill');
$sql = "
SELECT
skexp.id,
skexp.id_experience,
skexp.id_skills_details,
skd.description,
skd.id_skill
FROM skills_experience skexp
INNER JOIN skills_details skd
ON skd.id = skexp.id_skills_details
WHERE skexp.id_experience = $id_experience
ORDER BY skd.id_skill
";
$query = $this->getEntityManager()
->createNativeQuery($sql, $rsm)
->setParameter(1,$id_experience);
echo $query->getSQL();
$skexp = $query->getResult();
var_dump($skexp);
this is result
array(1) {
[0]=>
object(Admin\Entity\SkillsExperience)#471 (3) {
["id":"Admin\Entity\SkillsExperience":private]=>
string(1) "1"
["idExperience":"Admin\Entity\SkillsExperience":private]=>
NULL
["idSkillsDetails":"Admin\Entity\SkillsExperience":private]=>
object(Admin\Entity\SkillsDetails)#473 (3) {
["id":"Admin\Entity\SkillsDetails":private]=>
NULL
["description":"Admin\Entity\SkillsDetails":private]=>
string(18) "skillsname"
["idSkill":"Admin\Entity\SkillsDetails":private]=>
NULL
}
}
}
I expect 'Admin\Entity\SkillsDetails' in idSkillsDetails, but it is not
I can't obtain
skd.description,
skd.id_skill
how can I?
thanks

Ok i solved
$rsm = new ResultSetMapping;
$rsm->addEntityResult('Admin\Entity\SkillsExperience', 'ske');
$rsm->addFieldResult('ske', 'id', 'id');
$rsm->addFieldResult('ske', 'idExperience', 'id_experience');
$rsm->addJoinedEntityResult('Admin\Entity\SkillsDetails' , 'skd', 'ske', 'idSkillsDetails');
$rsm->addFieldResult('skd', 'idx', 'id');
$rsm->addFieldResult('skd', 'description', 'description');
$rsm->addJoinedEntityResult('Admin\Entity\Skills' , 'sk', 'skd', 'idSkill');
$rsm->addFieldResult('sk','idx2','id');
$sql = <<<EOT
SELECT
ske.id,
ske.id_experience,
skd.id as idx,
skd.description,
skd.id_skill,
sk.id as idx2
FROM skills_experience ske
LEFT JOIN skills_details skd
ON skd.id = ske.id_skills_details
LEFT JOIN skills sk
ON sk.id = skd.id_skill
WHERE id_experience = ?
ORDER BY sk.id
EOT;
$query = $this->em->createNativeQuery($sql,$rsm);
$query->setParameter(1,$id_experience);
$array = $query->getResult();
First of all it should be noted that when there are fields that have the same name in different tables, you must assign aliases.
When you add a join to the native query, you must use the following method
addJoinedEntityResult
There are 4 parameters
1) The class / entity on which the join is performed
2) The alias of the table on which the join is used in the query
3) The alias of the parent table used in the query
4) The field of the parent entity connected to the daughter (in my case idSkillsDetails to join the first and the second idSkill to join)
You must not, in the method for classes addFieldResult fathers, the field used to make the join
I hope it will be useful to others.

Related

sql command does not execute properly

I have a two tables in my database instructors and courses . I want to join them and for this reason wrote this code
$this->db->join('instructors', 'instructors.id = courses.instructor_id', 'left');
$query = $this->db->get_where('courses', array('courses_slug' => $slug));
return $query->row_array();
This code means:
SELECT * FROM `courses` LEFT JOIN `instructors` ON `instructors`.`id` = `courses`.`instructor_id` WHERE `courses_slug` = 'abituriyent-hazirligi'
But when I write this code to check:
$data['courses'] = $this->popular_courses_model->get_popular_courses($slug);
echo $data['courses']['id'];
die();
It writes the instructors id, not id of the course. Where can be the problem? Thanks in advance.
You are joining two table with columns of the same name ('id'). You need to be specific in your select for the columns and rename ('AS') if necessary.
select courses.id as course_id, instructor.id as instructor_id, ...
When using joins you should explicitly call out what columns you want returned like:
$select = "c.id, c.name, c.instructor_id, i.name instructor_name";
return $this->db->select($select)
//equivalent to "instructors as i"
->join('instructors i', 'i.id = c.instructor_id', 'left')
->where('c.courses_slug', $slug)
//equivalent to "courses as c"
->get('courses c')->row_array();

Symfony createNativeQuery, add count()

I have a query in a repository like :
$rsm = new ResultSetMapping;
$rsm->addEntityResult('\My\ProjectBundle\Entity\News', 't');
$rsm->addFieldResult('t', 'id', 'id');
$rsm->addMetaResult('t', 'account_id', 'account_id');
$qb = $this->_em->createNativeQuery(
'SELECT t.*
FROM news as t
LEFT JOIN
LEFT JOIN
WHERE
CONDITIONS CONDITIONS
',
$rsm
);
return $qb->getResult();
I simplified the above query which is used to retrieve the news that meet specific conditions.
I need to add a count() function to this query.
I have an other ManyToOne entity-relationship between Comment and News.
How to modify the query to get the comments number a given news has ?
I'm trying to add a left join to comment and add Count() in the select but I always get errors. How could I resolve this problem ?
Raw SQL with Doctrine is easier like this :
$em = $this->getDoctrine()->getManager()->getConnection();
$query = "
SELECT t.*
FROM news as t
LEFT JOIN
LEFT JOIN
WHERE
CONDITIONS CONDITIONS
";
$stmt = $em->prepare($query);
$stmt->execute();
$result = $stmt->fetchAll();

How to use CDbCriteria in Yii to apply SQL filters on Model

I try to get this mysql query to work with Yii model but i can't.
SELECT COUNT( qhc.countries_id) AS counter, q.question, co.name
FROM questions AS q , countries as co, questions_has_countries AS qhc
WHERE qhc.questions_id = q.id
AND co.id = qhc.countries_id
GROUP BY question
HAVING counter = 2
So far i have this, but somehow thou it seems ok, it doesnt work :
$criteria = new CDbCriteria();
$criteria->select = 'question, COUNT(countries_id) as counter';
$criteria->with = array('countries', 'categories');
$criteria->addInCondition('countries.id' , $_POST['Questions']['countries']);
$criteria->group = 'question';
$criteria->having = ('counter = 1');
$model = Questions::model()->findAll($criteria)
Pls help, I'am pretty new to Yii framework.
Thanks.
Sql from the log :
SELECT `t`.`question` AS `t0_c1`,
COUNT(countries_id) as counter, `t`.`id` AS `t0_c0`, `countries`.`id` AS
`t1_c0`, `countries`.`name` AS `t1_c1`, `categories`.`id` AS `t2_c0`,
`categories`.`name` AS `t2_c1` FROM `questions` `t` LEFT OUTER JOIN
`questions_has_countries` `countries_countries` ON
(`t`.`id`=`countries_countries`.`questions_id`) LEFT OUTER JOIN `countries`
`countries` ON (`countries`.`id`=`countries_countries`.`countries_id`)
LEFT OUTER JOIN `questions_has_categories` `categories_categories` ON
(`t`.`id`=`categories_categories`.`questions_id`) LEFT OUTER JOIN
`categories` `categories` ON
(`categories`.`id`=`categories_categories`.`categories_id`) WHERE
(countries.id=:ycp0) GROUP BY question HAVING (counter = 2). Bound with
:ycp0='1'
You have done most of work. Now you need to call the $criteria into model. Just like this
$rows = MODEL ::model()->findAll($criteria);
Where MODEL is model class of table which you want to apply criteria on.
To learn more about this you can follow this CActiveRecord Class.
Try to set together in CDbCriteria
...
$criteria->together = true;
$model = Question::model()->findAll($criteria);
when you use "as counter", your model must have a property named "counter" or it will not load it into your model.
if you don't have a property named "counter", try using another one of your models property that you are not selecting right now : "as someColumn"
and use condition or addCondition or .. instead of having
cheers

Yii Activerecord doesn't join with nested relation

I have defined the following criteria in Yii, and tries to use it to fetch an array of customers.
$criteria = new CDbCriteria(array(
"condition"=>"hidden = 0".(Yii::app()->user->GetState('is_admin') ? "" : " AND franchisesMunicipalities.franchise_id=".Yii::app()->user->getState('fid')),
"with" => array('municipality','municipality.franchisesMunicipalities')
));
$customers = Customers::model()->findAll($criteria);
This (i thought) should result in that Yii joined the table Customers with the table Municipalities, and then in the same query join the table Municipalities with the table Franchises_Municipalities. However it doesn't work since it doesn't join franchisesMunicipalities.
The resulting query is this
SELECT `t`.`id` AS `t0_c0`,
`t`.`municipality_id` AS `t0_c1`,
`t`.`personal_code_number` AS `t0_c2`,
`t`.`name` AS `t0_c3`,
`t`.`adress` AS `t0_c4`,
`t`.`zip` AS `t0_c5`,
`t`.`phone` AS `t0_c6`,
`t`.`mobile` AS `t0_c7`,
`t`.`email` AS `t0_c8`,
`t`.`hidden` AS `t0_c9`,
`municipality`.`id` AS `t1_c0`,
`municipality`.`county_id` AS `t1_c1`,
`municipality`.`name` AS `t1_c2`
FROM `customers` `t`
LEFT OUTER JOIN `municipalities` `municipality`
ON ( `t`.`municipality_id` = `municipality`.`id` )
WHERE ( hidden = 0
AND municipality.franchisesmunicipalities.franchise_id = 7 )
LIMIT 30
As you can see it only joins on one relation. The relations in the model should be correctly defined, since i am able to use them in other contexts.
Why doesn't this work?
According to http://www.yiiframework.com/doc/api/1.1/CActiveRecord#with-detail I believe you should be doing it this way:
$criteria = new CDbCriteria(array(
"condition"=>"hidden = 0".(Yii::app()->user->GetState('is_admin') ? "" : " AND franchisesMunicipalities.franchise_id=".Yii::app()->user->getState('fid'))
));
$customers = Customers::model()->with('municipality','municipality.franchisesMunicipalities')->findAll($criteria);
Hopefully that works for you.

Doing Join query using CDBCriteria

I am trying to do a Join query using CDBCriteria in Yii framework. The issue is the join query works successfully but it does not display the columns from other tables.
I am doing in the following way
$criteria = new CDbCriteria;
$criteria->order = 't.id desc';
$criteria->select = '*';
$criteria->join = ' INNER JOIN table2 INNER JOIN table3 INNER JOIN table4';
When i run this, I can see only the mail table1 columns displayed. Other columns are not shown.
In my model class, I have the relation has
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'user' => array(self::BELONGS_TO, 'DmPhoneUser', 'user_id'),
'command' => array(self::BELONGS_TO, 'DmOtaCommand', 'command_id'),
'partner' => array(self::BELONGS_TO, 'DmPartner', 'partner_id'),
);
}
********************************************************
public function actionGetHistory($start, $per_page)
{
$partner_id = '10';
$criteria = new CDbCriteria;
$criteria->order = 't.history_id desc';
$criteria->select = 't.*, table2.*';
$criteria->join = ' INNER JOIN table2 ON t.command_id = table2.command_id';
$result = Table_1_class::model()->with('command')->findAll();
$history_data = CJSON::encode($result);
echo $history_data;
}
here command_id is common in table1 and table2.
This is how I am using the criteria code.
As I said, Yii's Active Record implementation will only use columns which are defined in the table itself or the tables you are linking to through with, not arbitrary columns you return in the resultset.
Solution 1: Define a relation to table2, add that relation to with, and get rid of join. Then you'll probably need to convert each returned object to an array - CJSON::encode will not handle a model with relations well.
Solution 2: Use Yii::app()->db->createCommand("SQL query")->queryAll(); instead of Active Record. This will produce an array of arrays, which CJSON::encode will have no problem with.

Categories