How to add multiple "AND" conditions in a JOIN - symfony

I'm trying to add a "AND" condition to the join query but haven't been able to figure it out (not sure if it's even possible via Doctrine/Symfony). I'd appreciate any help with this.
->select('c, p')
->from(Customer::class, 'c')
->leftJoin('c.phones', 'p')
Example:-
SELECT c.*, p.*
FROM customer c
LEFT JOIN phone p ON c.id = p.customer_id AND p.is_main = 1 AND p.category = 0

You can use conditionType of the leftJoin function in queryBuilder check the documentation
public function leftJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null);
Example:
$qb->leftJoin('c.phones', 'p', 'WITH', 'p.is_main = 1 AND p.category = 0', 'p.id')

Use the WITH option like this:
$qb->leftJoin('c.phones', 'p', 'WITH', 'p.is_main = 1 AND p.category = 0', 'p.id')
Docs

Related

Query Builder Error in doctrine symfony using where in

I have a raw query which I would like to convert into doctrine ORM. It's basically a query which contains sub query to calculate total count.
SELECT Count(*) AS total_count
FROM (SELECT *
FROM content_item_languages
WHERE default_content_item_id IN (SELECT id AS default_content_item_id
FROM content_item
WHERE content_type = 1
AND is_translated = 0
AND modified_on >=
'$timePeriodStart'
AND is_active = 1)
AND language_id = '$language') AS t
I have written below doctrine ORM but still I am getting error
$em = $this->getEntityManager()->createQueryBuilder();
$totalPostSubselect = $em->addSelect('c.id AS defaultContentItemId')
->from('AppBundle\Entity\ContentItem\ContentItem', 'c')
->andWhere('c.contentType = 1')
->andWhere('c.isTranslated = 0')
->andWhere('c.modifiedOn >= :timeperiod')
->andWhere('c.isActive = :status')
->setParameter('status', 1)
->setParameter('timeperiod', $timePeriodStart)->getDQL();
$em = $this->getEntityManager()->createQueryBuilder();
$defaultSubSelect = $em->addSelect(['*'])
->from('AppBundle\Entity\ContentItem\ContentItemLanguages', 'cl')
->andWhere("cl.defaultContentItemId IN ($totalPostSubselect)")
->andWhere('cl.languageId = :language')
->setParameter('subSelect', $totalPostSubselect)
->setParameter('language', $language)->getDQL();
$em = $this->getEntityManager()->createQueryBuilder();
$mainQuerySelect = $em->addSelect(["count(*) as total_count"])
->from("(".$defaultSubSelect.")", 'AS t')->getQuery();
return $mainQuerySelect->getResult();
Here is the error I got
[Doctrine\ORM\Query\QueryException] [Syntax Error] line 0, col 13: Error: Expected Literal, got '*'
[Doctrine\ORM\Query\QueryException]
SELECT count(*) as total_count FROM (SELECT * FROM
AppBundle\Entity\ContentItem\ContentItemLanguages cl
WHERE (
cl.defaultContentItemId IN (SELECT c.id AS defaultContentItemId
FROM AppBundle\Entity\ContentItem\ContentItem c WHERE
c.contentType = 1 AND
c.isTranslated = 0 AND
c.modifiedOn >= :timeperiod AND c.isActive = :status))
AND cl.languageId = :language) AS t
can anyone suggest, in exactly where I am doing wrong ?
In doctrine query language you can't SELECT *, instead you have to deal with objects. For your example something like:
$mainQuerySelect = $em->addSelect("count(t.id) as total_count")
->from("(".$defaultSubSelect.")", 'AS t')->getQuery();

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

DQL access id from object property with left join

I realized this sql which works without problems
SELECT meeting.name, meeting.date, community.name, participation.isPresent, participation.user_id
FROM meeting
INNER JOIN community
ON meeting.community_id = community.id
AND community.is_active = 1
LEFT join participation
ON meeting.id = participation.meeting_id
AND participation.user_id = 1078
WHERE meeting.date >= CURRENT_DATE()
ORDER BY meeting.date DESC
I'm trying to reproduce it with the doctrine query builder but I never got the right result. The user id part doesn't seem to be part of the leftJoin function but is applied to the request globally, which is not what I want.
public function getNextMeetings()
{
$qb = $this->createQueryBuilder('m')
->select('m.name AS meeting, m.date, c.name AS community, p.isPresent', 'IDENTITY(p.user) AS user')
->innerJoin('m.community', 'c')
->where('c.isActive = true')
->leftJoin('m.participations', 'p')
//->leftJoin('p.user', 'u')
//->where('u.id = 1078 OR u.id IS NULL')
//->where('IDENTITY(p.user) = 1078')
->andWhere('m.date >= CURRENT_DATE()')
->orderBy('m.date', 'DESC');
return $qb->getQuery()->execute();
}
My comments are what I tried to fix this issue.
Check Working with QueryBuilder: High level API methods
More precisely, the definition od leftJoin() function:
public function leftJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null);
You can place a condition on the joined Entity by:
use Doctrine\ORM\Query\Expr;
->leftJoin('m.participations', 'p', Expr\Join::WITH, 'p.user = :userId')
->setParameter('userId', 1078)
Note you do not need a condition for "meeting.id = participation.meeting_id", as this is autoapplied by the relation m.participations to the join constructed.

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

innerjoin query in drupal 7

I am applying this query for below D6 query , not working ..dont know wat wrong i'm doing ....does innerjoin fails in some condition
$result = db_select('px_slides','s')
->join('node','n','s.vid = n.vid')
->fields('s',array('tissue_type','body_site'))
->fields('n',array('sticky','title'))
->condition('n.status','1','=')
->condition('s.cid','126','=')
->execute()->fetchObject();
drupal 6 query i have:
$result = db_query('
SELECT n.nid, n.vid, n.sticky, n.title, n.created, s.cid, s.ref_id, s.viewurl, s.specimen_type, s.tissue_type, s.body_site, s.test_type, s.algorithm, s.result
FROM {px_slides} s INNER JOIN {node} n ON n.vid = s.vid
WHERE n.status = 1 ')->execute();
You need to put your call to ->join() on a separate line altogether, as it doesn't return the query object:
$query = db_select('px_slides','s')
->fields('s',array('tissue_type','body_site'))
->fields('n',array('sticky','title'))
->condition('n.status','1','=')
->condition('s.cid','126','=');
$query->join('node','n','s.vid = n.vid');
$result = $query->execute()->fetchObject();
The join method does not chain like that. You will have to do something like:
$query = db_select('px_slides','s')
->join('node','n','s.vid = n.vid');
$query->fields('s',array('tissue_type','body_site'))
->fields('n',array('sticky','title'))
->condition('n.status','1','=')
->condition('s.cid','126','=');
$result = $query->execute()->fetchObject();
Also you can use the to string magic method to see the query it is going to execute.
$query->__toString();
Try this...
$query = db_select('px_slides', 's');
$query->innerJoin('node,'n','s.vid = n.vid');
$query->fields('s',array('tissue_type','body_site'));
$query->fields('n',array('sticky','title'));
$query->condition('n.status','1');
$query->condition('s.cid','126');
$result= $query->execute()->fetchAll(PDO::FETCH_ASSOC);

Resources