次の SQL クエリがあります。
SELECT DISTINCT u.id
FROM User u
LEFT JOIN usergroup_user ug1 ON u.id = ug1.user_id
LEFT JOIN usergroup_user ug2 ON ug1.user_id = ug2.user_id AND ug2.usergroup_id = :groupid
WHERE ug2.usergroup_id IS NULL
これは、usergroup :groupid に含まれていないすべてのユーザーを返します。ユーザーが除外されたグループに加えて他のグループのレコードを持っている場合、それらも必要ありません。
SQLクエリは機能しますが、このクエリをDQL、Doctrine for Symfony2で書く方法はありますか?
私はこれを試しました:
SELECT DISTINCT u.id
FROM AcmeDemoBundle:User u
LEFT JOIN u.groups ug1
LEFT JOIN u.groups ug2 WITH ug1 = ug2 AND ug2 = :groupid
WHERE ug2 IS NULL
しかし、うまくいきません。DQL ステートメントは、次の SQL ステートメントに変換されます。
SELECT DISTINCT u0_.id AS id0
FROM User u0_
LEFT JOIN usergroup_user u2_ ON u0_.id = u2_.user_id
LEFT JOIN UserGroup u1_ ON u1_.id = u2_.usergroup_id
LEFT JOIN usergroup_user u4_ ON u0_.id = u4_.user_id
LEFT JOIN UserGroup u3_ ON u3_.id = u4_.usergroup_id AND (u1_.id = u3_.id AND u3_.id = :groupid)
WHERE u3_.id IS NULL
結合テーブルにまたがり、セットを台無しにするため、これは明らかに良くありません。
数学的に言えば、セットを使用して、次のようにしています: result = A\B (A にあるが B にはない要素)、A = 「すべてのユーザー」、および B = 「グループ :groupid 内のすべてのユーザー」 "。
私がやりたいことはDQLを使用して可能ですか、それともこの場合はSQLを使用する必要がありますか? 結合テーブルを独自のエンティティに変換せずに実行できますか?
テストデータ
ORM スキーマ:
Resources/config/doctrine/User.orm.yml
Acme\DemoBundle\Entity\User: type: entity table: null fields: id: type: integer id: true generator: strategy: AUTO manyToMany: groups: targetEntity: UserGroup mappedBy: users
Resources/config/doctrine/UserGroup.orm.yml
Acme\DemoBundle\Entity\UserGroup: type: entity table: null fields: id: type: integer id: true generator: strategy: AUTO manyToMany: users: targetEntity: User inversedBy: groups
SQL データ:
INSERT INTO `User` VALUES (1),(2),(3),(4);
INSERT INTO `UserGroup` VALUES (1),(2),(3),(4);
INSERT INTO `usergroup_user` VALUES (1,1),(1,2),(1,3),(2,2),(3,4);