left join with external query in query-builder - symfony

I need to create that query in query builder
SELECT * FROM table1 LEFT JOIN table2 ON (table1.parent_id = table2.id OR table1.id = table2.id) WHERE table2.id IS NULL;
I already've got
$er->createQueryBuilder('p')
->leftJoin('Bundle2:table2', 'n')
->where('p.parent = n.id')
->andWhere('p.id = n.id');
but don't know how to add external WHERE to query ?

Try this:
return $this->createQueryBuilder('t1')
->leftJoin('t1.table2', 't2')
->where('t1.parent = t2.id OR t1.id = t2.id')
->andWhere('t2.id IS NULL')
->getQuery()
->getResult();

Related

Doing a subquery inside a where with Doctrine 2 querybuilder

I am trying (without success) to translate this SQL query inside a Doctrine2 querybuilder. How should I do to include the subselect inside a Where with Querybuilder ?
SQL query I am trying to implement with querybuilder :
SELECT * FROM `message` A
WHERE A.id =
(SELECT B.id FROM `message` B
WHERE (A.user_id = B.user_id AND A.receiver_id = B.receiver_id) OR (A.user_id = B.receiver_id AND A.receiver_id = B.user_id)
ORDER BY creationdate DESC
LIMIT 1)
So far, I tried something like this in Message repository but I guess I am far away from the good way to do it :
public function getConversations()
{
$qb = $this
->createQueryBuilder('A')
->Where('A.id IN
(SELECT B.id FROM Message B
WHERE (A.user_id = B.user_id AND A.receiver_id = B.receiver_id) OR (A.user_id = B.receiver_id AND A.receiver_id = B.user_id)
ORDER BY creationdate DESC
LIMIT 1')
;
return $qb
->getQuery()
->getResult()
;
}
}
This trigger error message:
Error: Class 'Message' is not defined.
For people interested I finally found a solution. I did the query like this (if someone has another solution I am very interested):
public function getConversations()
{
$rawSql = "SELECT * FROM `message` A
WHERE A.id =
(SELECT B.id FROM `message` B
WHERE (A.user_id = B.user_id AND A.receiver_id = B.receiver_id) OR (A.user_id = B.receiver_id AND A.receiver_id = B.user_id)
ORDER BY creationdate DESC
LIMIT 1)
";
$stmt = $this->getEntityManager()->getConnection()->prepare($rawSql);
$stmt->execute([]);
return $stmt->fetchAll();
}

DqlBuilder don't return values but mysql do

I have method findByTag() which should return entites with %#i% but it won't. This is sql which dql builded:
SELECT p0_.id AS id_0, p0_.content AS content_1, p0_.date AS date_2, p0_.user_id AS user_id_3 FROM post p0_ INNER JOIN user u1_ ON p0_.user_id = u1_.id LEFT JOIN points p2_ ON p0_.id = p2_.post_id LEFT JOIN comments c3_ ON p0_.id = c3_.post_id WHERE p0_.content LIKE '%#i%' ORDER BY p0_.date DESC LIMIT 20 if i enter it to mysql it return it ok.
Anybody have an idea?
$dql = $this->createQueryBuilder('p')
->innerJoin('p.user', 'c')
->leftJoin('p.points', 'pp')
->leftJoin('p.comments', 'cc')
->Where('p.content LIKE \'%#i%\'')
->setMaxResults($max)
->orderBy('p.date','DESC');
$dql->getQuery()
->getResult();
return $dql;
try it
$dql = $this->createQueryBuilder()
->from('YourBundleName:YourEntityName', 'p')
->innerJoin('YourBundleName.user', 'c')
->leftJoin('YourBundleName.points', 'pp')
->leftJoin('YourBundleName.comments', 'cc')
->Where('p.content LIKE \'%#i%\'')
->setMaxResults($max)
->orderBy('p.date','DESC');
return $dql->getQuery()->getResult();

Doctrine left join where joined table is null shows results

the goal of this query is to show records from table orders that don't have any shipments created yet. Here is how it should be done in SQL:
SELECT *
FROM orders
LEFT JOIN orders_shipments shipments ON orders.trx_id = shipments.trx_id
WHERE shipments.shipment_id IS NULL
AND orders.purchase_date IS NOT NULL
AND orders.fulfillment_channel = 'MFN';
The following query shows 0 results. Vs the following:
$qb = $this->createQueryBuilder('orders');
$qb->select('orders, shipments')
->leftjoin('orders.shipments', 'shipments')
->Where('shipments.id IS NULL')
->ANDWhere('orders.purchaseDate IS NOT NULL')
->ANDWhere('orders.fulfillmentChannel = :a')->setParameter('a', 'MFN');;
$results = $qb->getQuery()
->getResult();
return $results;
Does show results. Why is that and how to fix it?
Not sure why but I had to use GROUP and HAVING to get it to work:
$qb = $this->createQueryBuilder('orders');
$qb->select('orders, shipments')
->leftjoin('orders.shipments', 'shipments')
->Where('shipments.id IS NULL')
->ANDWhere('orders.purchaseDate IS NOT NULL')
->ANDWhere('orders.fulfillmentChannel = :a')->setParameter('a', 'MFN')
->GroupBy('orders.id')
->having('count(shipments) = 0');
$results = $qb->getQuery()->getResult();

Android Sqlite Multiple Joins with Alias does not return anything

I have this query:
Cursor res = db.rawQuery("SELECT t1.Id, t2.EmpId FROM table1 t1
LEFT JOIN table2 t2 ON t1.t2Id = t2.Id
LEFT JOIN table3 t3 ON t1.t3Id = t3.Id
WHERE t1.Id = 90909", null);
Now when I go
if(res.moveToFirst()){
do{
MyObject obj = new MyObject();
obj.Id = res.getInt(res.getColumnIndex("t1.Id"));
MyObjectAsProperty objProp = new MyObjectAsProperty();
objProp.EmpId = res.getInt(res.getColumnIndex("t2.EmpId"));
}while(res.moveToNext());
}
The objProp.EmpId returns nothing (or 0). I looked at the cursor columns and it's Fields basically did not include the table alias names. How do I go about getting the values of those aliased fields?
Thanks!
EDIT
Apologies. I forgot to add that if for example it's referencing the same other table multiple times with the same field.
Here's updated query
Cursor res = db.rawQuery("SELECT t1.Id, t2.EmpId, t2b.EmpId FROM table1 t1
LEFT JOIN table2 t2 ON t1.t2Id = t2.Id
LEFT JOIN table2 t2b ON t1.t2bId = t2b.Id
WHERE t1.Id = 90909", null);
if(res.moveToFirst()){
do{
MyObject obj = new MyObject();
obj.Id = res.getInt(res.getColumnIndex("t1.Id"));
MyObjectAsProperty objProp = new MyObjectAsProperty();
objProp.EmpId = res.getInt(res.getColumnIndex("t2.EmpId"));
MyObjectAsProperty objProp2 = new MyObjectAsProperty();
objProp2 .EmpId = res.getInt(res.getColumnIndex("t2bId.EmpId"));
}while(res.moveToNext());
}
The documentation says:
The name of a result column is the value of the "AS" clause for that column, if there is an AS clause. If there is no AS clause then the name of the column is unspecified and may change from one release of SQLite to the next.
So you must use AS:
SELECT t1.Id AS ObjID, t2.EmpId AS EmpId, ...

How to write the INNER JOIN in dql

This is my select and it works in workbench fine, but how did i write the INNER JOINS for doctrine?
$qb = $em->createQuery(
"SELECT oh.objektnummer, oh.idSubunternehmer, oh.datum, oh.typ, oh.outbox
FROM MBSAllgemeinBundle:ObjektHistory oh
INNER JOIN MBSAllgemeinBundle:Objekt o ON o.objektnummer = oh.objektnummer AND o.idSubunternehmer = oh.idSubunternehmer
INNER JOIN MBSAllgemeinBundle:Subunternehmer s ON s.subunternehmernummer = o.id_subunternehmer
INNER JOIN MBSAllgemeinBundle:SubunternehmerUser su ON su.id_subunternehmer = s.subunternehmernummer
WHERE su.idUser = 1"
);
Try this syntax in your repository :
return $this->createQueryBuilder('oh')
->select('partial oh.{id, objektnummer, idSubunternehmer, datum, typ, outbox}')
->innerJoin('MBSAllgemeinBundle:Objekt', 'o', 'ON', 'o.objektnummer = oh.objektnummer AND o.idSubunternehmer = oh.idSubunternehmer')
->addSelect('o')
// other INNER JOIN
// other INNER JOIN
->where('su.idUser = :id')
->setParameter('id', 1)
->getQuery()
->getResult()
;

Resources