I first was wondering if nested queries were allowed in DQL. I found that at least partially the are (see here). So I'm wondering if they can do what I need.
The situation is the following: I have the table ProjectNotification
where I have all the notifications for all projects and all users. I then have a UserXNotification
table where I store the ids of the notifications that a given user has read. I want to be able to extract the total number of unread notifications (not originated by the current user) per project. The following query works (without the inner select). But this one gives error.
$query = $em->createQuery(
'SELECT IDENTITY (n.project), COUNT(n.id)
FROM AppBundle:ProjectNotification n
WHERE n.project IN (:projectIDs)
AND n.user <> :user
AND n.id NOT IN (
SELECT uxn.projectNotification
FROM AppBundle:UserXNotification uxn
WHERE uxn.user = :user
AND uxn.read = false
)
GROUP BY n.project
')->setParameter('projectIDs', $projectIDs)
->setParameter('user', $user);
$notifQueryResult = $query->getResult();
The error in specific is:
QueryException: [Semantical Error] line 0, col 354 near 'projectNotification': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
For completeness here is the UsersXNotifications entity:
class UserXNotification
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="User")
*/
protected $user;
/**
* @ORM\ManyToOne(targetEntity="ProjectNotification")
*/
protected $projectNotification;
/**
* @ORM\Column(type="boolean")
*/
protected $readStatus;
And here is the ProjectNotification entity
class ProjectNotification
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// SOME IRRELEVANT FIELDS
/**
* @ORM\ManyToOne(targetEntity="Project")
*/
protected $project;
/**
* @ORM\ManyToOne(targetEntity="User")
*/
protected $user;
Actually the first version of the query I wrote had SELECT uxn.projectNotification.id
instead of SELECT uxn.projectNotification
but it gave me this error:
QueryException: [Semantical Error] line 0, col 378 near 'id': Error: Class AppBundle\Entity\UserXNotification has no field or association named projectNotification.id
I also tried:
...
AND n NOT IN (
SELECT uxn.projectNotification
to no avail. I know that the inner query is retrieving objects, that is why I tried this last one. The error in this case was:
QueryException: [Semantical Error] line 0, col 355 near 'projectNotification': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
I hope it's doable without having to write in native sql and hydrate :/
Any hint?