Reputation: 10583
I have the following tables, User, Project and Images.
A User has a one to many relationship with Projects and Images. Each Project and Image is owned by a User.
A Project has a many to many relationship with Images. So each Project can have many Images, and an Image can appear within many Projects.
I want to write a DQL query to get all Images, for a specific User that are not included in any Projects. This I can write in SQL.
Is writing in SQL the best way to go?
Or should I be using DQL to do this?
I have tried writing the DQL but its hard work!
Edit
From within my Image Repo I am now doing this
$qb = $this->createQueryBuilder("i");
$qb->select("i")
->from('MyBundleName:User','u')
->innerJoin('u.images', 'user_images')
->where('IDENTITY(u.id) = :user_id')
->andWhere('NOT EXISTS (
SELECT p
FROM MyBundleName:Project p
WHERE user_images MEMBER of p.images
)')
->setParameter('user_id', $user_id);
I have replace the /
syntax with :
for my classes as they failed when using /
I am still getting this error though;
[Semantical Error] line 0, col 131 near 'id) = :user_id': Error: Invalid PathExpression. Must be a SingleValuedAssociationField.
The function createQueryBuilder
requires an alias, I am passing it "i"
- is that right?
I then give it "i"
again when calling select
?
If I remove the innerJoin
then it works, but the results are wrong. It returns all images even if they do exist within an project.
Upvotes: 1
Views: 203
Reputation: 32392
I don't know what your entities look like but given the relations something like this should work. The key is combining NOT EXISTS
and MEMBER OF
(you want to make sure that for all returned images no project exists that the image is a member of).
$qb->select("i")
->from('MyBundle\Entity\User','u')
->innerJoin('u.images','i')
->where('IDENTITY(u) = :user_id')
->andWhere('NOT EXISTS (
SELECT p
FROM MyBundle\Entity\Project p
WHERE i MEMBER of p.images
)')
->setParameter('user_id', $user_id);
Upvotes: 1
Reputation: 7606
I can't say how difficult it would be in DQL, but I can tell you that in SQL it sounds pretty simple:
SELECT I.*
FROM IMAGES I
INNER JOIN USERS U ON (I.USER_ID = U.USER_ID)
WHERE NOT EXISTS (
SELECT *
FROM PROJECTS P, PROJECT_IMAGES PI
WHERE P.USER_ID = U.USER_ID
AND PI.PROJECT_ID = P.PROJECT_ID
AND I.IMAGE_ID = PI.IMAGE_ID
)
Images owned by a user which does not exist in any project that the user owns.
Upvotes: 1