Query builder in Doctrine_Table? - php

I have a previously writen query in other Doctrine project using Query Builder.
$qb->select('c', 'm')
->from('Chapter c')
->leftJoin('c.Book m')
->orderBy('c.chapterno DESC')
->addOrderBy('m.id ASC')
->groupBy('m.id')
->where('c.chapterno = (SELECT MAX(v.chapterno) FROM Chapter v WHERE v.mid = m.id)')
->limit($max);
How can I replicate this in my inherited class from Doctrine_table in symfony?
I am using symfony 1.4

In your ChapterTable class, something like the following:
public function getChapters($max)
{
$qry = self::getInstance()
->createQuery("c")
->leftJoin('c.Book m')
->orderBy('c.chapterno DESC')
->addOrderBy('m.id ASC')
->groupBy('m.id')
->where('c.chapterno = (SELECT MAX(v.chapterno) FROM Chapter v WHERE v.mid = m.id)')
->limit($max);
return $qry->execute();
}
Then you can call this with eg:
$myMaxValue = 25;
$results = Doctrine::getTable("Chapter")->getChapters($myMaxValue);

Here is a nice solution to organize your queries:

Related

How can I generate this query in doctrine?

How can I generate this query in doctrine or query builder?
SELECT EndDate from helios.fsa_audits order by StartDate desc limit 1;
Any idea or Advice about how to make it?
Seeing your entity here, in your controller you can try this:
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder()
->select(array('a'))
->from(FsaAudits::class, 'a')
->orderBy("a.StartDate","DESC")
->setMaxResults(1);
$resultset = $qb->getQuery()->getResult();
if (count($resultset) <= 0) {
$fsaobj = $resultset[0];
echo $fsaobj->getEndDate();
}
See Working with query builder

How to use "distinct on" with doctrine?

I try to use "distinct on" with doctrine but I get the following error:
Error: Expected known function, got 'on'
class Report extends EntityRepository
{
public function findForList() {
$queryBuilder = $this->createQueryBuilder('r');
$queryBuilder->select('distinct on (r.parentId)')
->orderBy('r.parentId')
->orderBy('r.date', 'DESC');
return $queryBuilder->getQuery()->getResult();
}
}
How could I implement the following query?
select distinct on (r.parent_id)
r.parent_id,
r.id,
r.name
from frontend.report r
order by r.parent_id, r.date desc;
Apparently it doesn't seem possible to do this with the query builder. I tried to rewrite my query in different ways:
select * from frontend.report r
where
r.id in (
select distinct
(select r3.id from frontend.report r3
where r3.parent_id = r.parent_id
order by r3.date desc limit 1) AS id
from frontend.report r2);
But doctrine doesn't support LIMIT:
public function findForList() {
$qb3 = $this->_em->createQueryBuilder();
$qb3->select('r3.id')
->from('MyBundle:frontend\report', 'r3')
->where('r3.parentId = r2.parentId')
->orderBy('r3.date', 'DESC')
//->setMaxResults(1)
;
$qb2 = $this->_em->createQueryBuilder();
$qb2->select('(' . $qb3->getDql() . ' LIMIT 1)')
->from('MyBundle:frontend\report', 'r2')
->distinct(); // groupBy('r2.parentId')
$queryBuilder = $this->createQueryBuilder('r');
$queryBuilder->where(
$queryBuilder->expr()->in('rlt.id', $qb2->getDql())
);
return $queryBuilder->getQuery()->getResult();
}
I think the only solution is to use native SQL queries.
This response is for someone that yet looking for the solution in similar cases.
If you need a sample "DISTINCT" you can use:
$queryBuinder->select('parentId')
->distinct('parentId');
but if you want a "DISTINCT ON" you should use Native SQL instead of Query Builder, check out the manual here: Doctrine Native SQL
Just remove the on word :
$queryBuilder->select('distinct r.parentId')
->orderBy('r.parentId')
->orderBy('r.date', 'DESC');

Select One column Doctrine DQL

I need a simple column for a table.
By example a table "project", with column id, name and year.
If I do:
$q = Doctrine_Query::create()
->select('a.pro_id')
->from('fndr_proyecto a')
->where('a.pro_id =?',1);
$pro = $q->execute();
json_encode($pro->toArray());
The answer is all column like
{"id":1,"name":"Project name","year":2013}
but I need only one column. I expect:
{"id":1}
It is with DQL because with native SQL work fine.
The ORM is build automaticaly with a Visual Paradigm.
This is because Doctrine hydrate the response with all the object information, so all columns.
You need to use a different hydration method, there are many one, but let's focus on 5 of them:
HYDRATE_RECORD, the default one
HYDRATE_ARRAY
HYDRATE_NONE
HYDRATE_SCALAR
HYDRATE_ARRAY_SHALLOW
You need the HYDRATE_ARRAY_SHALLOW hydration method. Here's why.
HYDRATE_RECORD
$q = Doctrine_Query::create()
->select('a.pro_id')
->from('fndr_proyecto a')
->where('a.pro_id = ?',1);
$pro = $q->execute(array(), Doctrine_Core::HYDRATE_RECORD);
var_dump(json_encode($pro->toArray()));
This will hydrate the result using object, and also hydrate relations (if you use a leftJoin inside your query). Since it returns object, we need to call toArray() to be able to send a propre json:
[{"id":1,"name":"Project name","year":2013}]"
HYDRATE_ARRAY
$q = Doctrine_Query::create()
->select('a.pro_id')
->from('fndr_proyecto a')
->where('a.pro_id = ?',1);
$pro = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
var_dump(json_encode($pro));
This will hydrate result as an array an automatically add the primary key:
[{"id":"1","pro_id":"1"}]"
HYDRATE_NONE
$q = Doctrine_Query::create()
->select('a.pro_id')
->from('fndr_proyecto a')
->where('a.pro_id = ?',1);
$pro = $q->execute(array(), Doctrine_Core::HYDRATE_NONE);
var_dump(json_encode($pro));
This won't hydrate result, and return just values:
[["1"]]"
HYDRATE_SCALAR
$q = Doctrine_Query::create()
->select('a.pro_id')
->from('fndr_proyecto a')
->where('a.pro_id = ?',1);
$pro = $q->execute(array(), Doctrine_Core::HYDRATE_SCALAR);
var_dump(json_encode($pro));
This will hydrate result from the select but with key index as the column name with the table alias:
[{"a_pro_id":"1"}]"
HYDRATE_ARRAY_SHALLOW
$q = Doctrine_Query::create()
->select('a.pro_id')
->from('fndr_proyecto a')
->where('a.pro_id = ?',1);
$pro = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY_SHALLOW);
var_dump(json_encode($pro));
This will hydrate result from the select but with key index as the column name without the table alias:
"[{"pro_id":"1"}]"
I'm not sure what version of Doctrine j0k was using. It provided some answers, but I did have trouble finding Doctrine_Query and Doctrine_Core classes. I am using Doctrine 2.3.4. The following worked for me.
public static function getAllEventIDs($em) {
return parent::getAllFromColumn('\path\to\Entity\entityName', 'id', $em);
}
public static function getAllFromColumn($tableName, $columnName, $em) {
$q = $em->createQueryBuilder('t')
->select("t.$columnName")
->from($tableName, 't');
$q = $q->getQuery();
$result = $q->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR);
return $result;
}
This did however return a array of arrays. ie, the id of the first event was is
$result[0]['id'];
As of Doctrine 2.10, you can use Scalar Column Hydration:
$query = $em->createQuery('SELECT a.id FROM CmsUser u');
$ids = $query->getResult(Query::HYDRATE_SCALAR_COLUMN);
or
$ids = $query->getSingleColumnResult();
and this results in a flat array
[412, 959, 1234]

Using subqueries with doctrine / Errors with aliases

I'm trying to make a simple query with a subquery in a orWhere clause (with Doctrine).
As always, Doctrine tries to rename every aliases and completely destroys the queries...
Here's an example:
$q = Doctrine_Query::create()
->from('Actualite a')
->where('a.categorie_id =?', $id)
->orWhere('a.categorie_id IN (select id from cat.categorie as cat where cat.categorie_id =?)', $id)
->execute();
Which in MySQL would make something like:
SELECT *
FROM actualite a
WHERE a.categorie_id = 1 OR a.categorie_id IN (SELECT cat.id FROM categorie cat WHERE cat.categorie_id = 1);
Everything is right about it, but then again Doctrine destroys it:
Couldn't find class cat
Every time I try to do something a little complex with Doctrine, I have errors with aliases. Any advice or ideas about how to fix this?
Thanks!
The SQL example you've provided is fine but the corresponding Doctrine syntax has a couple of errors. Here's a clean version:
$q = Doctrine_Query::create()
->select('a.*')
->from('Actualite a')
->where('a.categorie_id = ?', $id)
->orWhere('a.categorie_id IN (SELECT cat.id FROM Categorie cat WHERE cat.categorie_id = ?)', $id)
->execute();
You should use createSubquery() to explicitely tell doctrine about your nested subquery. So your query should look something like this:
$q = Doctrine_Query::create()
->select('a.*')
->from('Actualite a')
->where('a.categorie_id = ?', $id)
;
$subquery = $q->createSubquery()
->select("cat.id")
->from("Categorie cat")
->where("cat.categorie_id = ?", $id)
;
$q->orWhere('a.categorie_id IN ('.$subquery->getDql().')')->execute();
Another example can be found here:
http://www.philipphoffmann.de/2012/08/taming-doctrine-subqueries/
I think you query should be like this add the select and remove as
$q = Doctrine_Query::create()
->select('a.id')
->from('Actualite a')
->where('a.categorie_id =?', $id)
->orWhere('a.categorie_id IN (select id from cat.categorie cat where cat.categorie_id =?)', $id)
->execute();
Try this may help you.
Thanks

Doctrine Join DQL

I's like to do a join between 2 tables on a specific ID. At the moment, I have this DQL:
$q = Doctrine_Query::create()
->select('e.*, i.itemName, i.itemtypeId')
->from('Model_EventItem e')
->leftJoin('Model_Item i ON e.itemId = i.itemId')
->where('e.eventitemId = ?', $event->eventId)
->orderBy('i.itemName ASC');
The result is empty, although my eventId has a value ... Can you help me please? I there somewhere a tutorial on DQL-joins? I don't get it right with the help of the Doctrine documentation.
Thanks!
PS I have doctrine working in combination with Zend Framework.
you need add a relation to the model and join the tables using the relation
$q = Doctrine_Query::create()
->select('e.*, i.itemName, i.itemtypeId')
->from('Model_EventItem e')
->leftJoin('Model_EventItem.Model_Item i')
->where('e.eventitemId = ?', $event->eventId)
->orderBy('i.itemName ASC');
you should change the name in the left join from Model_EventItem to e
$q = Doctrine_Query::create()
->select('e.*, i.itemName, i.itemtypeId')
->from('Model_EventItem e')
->leftJoin('Model_EventItem.Model_Item i')
->where('e.eventitemId = ?', $event->eventId)
->orderBy('i.itemName ASC');
$q = Doctrine_Query::create()
->select('e.*, i.itemName, i.itemtypeId')
->from('Model_EventItem e, e.Model_Item i')
->where('e.eventitemId = ?', $event->eventId)
->orderBy('i.itemName ASC');

Categories