Ok, so I'm sure that was a freakishly confusing question. Let me try to explain more clearly...
Problem:
Schema is simple, essentially:
I'm working with a very large data set and need to compile everything into just 1 efficient query. There are several one to many relationships and I'm attempting to "filter" the data set.
I want all preceptor associations for events that have at least 1 preceptor matching the given ID.
For example, I have an "event" entity that can have zero or several "preceptors" associated with it. My user's filter needs to allow them to choose a "preceptor" and return all events with the given preceptor ID. Well that's easy enough. BUT I need to still list the other preceptors - I need the other relationships to still be queried, but require at least 1 of the associations to match the given criteria.
I hope that makes a bit more sense. I can always "filter" the data once it's queried, but I'd like to avoid getting irrelevant data since it's such a huge data set.
Here's a snippet of my code:
$qb->select($selectPartials)
->from('EventLegacy', 'e')
->leftJoin('e.site', 's')
->leftJoin('s.program_site_associations', 'psa')
->leftJoin('e.base', 'b')
->leftJoin('b.program_base_associations', 'pba')
->leftJoin('e.preceptor_associations', 'pa')
->leftJoin('pa.preceptor', 'pre')
->andWhere('e.program = ?3')
->andWhere('e.start_datetime >= ?1')
->andWhere('e.start_datetime <= ?2')
->andWhere('psa.active = true')
->andWhere('psa.program = ?3')
->andWhere('pba.active = true')
->andWhere('pba.program = ?3')
->andWhere('pre.id = ?4')
->orderBy('e.start_datetime')
->setParameter(1, $startDate)
->setParameter(2, $endDate)
->setParameter(3, $program)
->setParameter(4, $preceptorId);
return $qb->getQuery()->getArrayResult();
An equivalent SQL Query:
SELECT *
FROM EventData e0_
LEFT JOIN AmbulanceServices a1_ ON e0_.site_id = a1_.AmbServ_id
LEFT JOIN ProgramSiteData p2_ ON a1_.AmbServ_id = p2_.AmbServ_id
LEFT JOIN AmbServ_Bases a3_ ON e0_.StartBase_id = a3_.Base_id
LEFT JOIN ProgramBaseData p4_ ON a3_.Base_id = p4_.Base_id
LEFT JOIN EventPreceptorData e5_ ON e0_.Event_id = e5_.Event_id
LEFT JOIN PreceptorData p6_ ON e5_.Preceptor_id = p6_.Preceptor_id
WHERE (e0_.Program_id = 287)
AND (e0_.start_datetime >= ?)
AND (e0_.start_datetime <= ?)
AND (p2_.Active = 1)
AND (p2_.Program_id = 287)
AND (p4_.Active = 1)
AND (p4_.Program_id = 287)
AND (p6_.Preceptor_id = 179293)
ORDER BY e0_.start_datetime ASC
Here's some fake data that may be helpful.
Let's say I have 3 events total. (id, name)
1, eventA
2, eventB
3, eventC
eventA has 2 preceptors associated with it, eventB doesn't have any, and eventC has 1. So, our EventPreceptorData table would have something like this:
(id, event_id, preceptor_id)
1,1,1
2,1,2
3,3,1
Our prceptors (PreceptorData) may look something like this (id, name)
1, Bob
2, Chris
So if I were searching for Bob, I would want to see events A and C, and I would want my output to be:
eventA
Preceptors: Bob, Chris
eventB
Preceptors: Bob
My issue is that "Chris" does not get listed (Which makes perfect sense considering my query).