我有以下 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
这样做是返回所有不在用户组:groupid 中的用户。如果用户除了排除的组之外还有其他组的记录,我也不想要这些。
SQL 查询有效,但有没有办法在 DQL、Symfony2 的 Doctrine 中编写这个查询?
我试过这个:
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
这显然不好,因为它跨越了连接表并弄乱了集合。
用数学术语来说,使用集合,我这样做:结果 = A\B(在 A 中但不在 B 中的元素),A =“所有用户”,B =“组中的所有用户:groupid ”。
我想用 DQL 做些什么,还是应该只使用 SQL 来处理这种情况?可以在不将连接表变成它们自己的实体的情况下完成吗?
测试数据
ORM 架构:
资源/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
资源/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);