У меня есть следующий SQL-запрос:Доктрина DQL LEFT JOIN установить разницу
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, 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 для этого случая? Можно ли это сделать, не превращая таблицы соединений в собственные?
Тестовые данные
ОРМ схемы:
Ресурсы/конфигурации/Доктрина/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
Ресурсы/конфигурации/Доктрина/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);