2013-07-01 73 views
0

我有以下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,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架構:

  • 資源/配置/教義/ 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); 

回答

1

我想我發現就在我張貼,在側邊欄,它在可能的非相關的上下文中提到MEMBER OF「相關」鏈接答案。

我DQL現在看起來是這樣的:

SELECT DISTINCT u.id 
    FROM AcmeDemoBundle:User u 
    WHERE :group NOT MEMBER OF u.groups 

它轉換爲這樣的:

SELECT DISTINCT u0_.id AS id0 
    FROM User u0_ 
    WHERE NOT EXISTS (
     SELECT 1 
     FROM usergroup_user u1_ 
     INNER JOIN UserGroup u2_ ON u1_.usergroup_id = u2_.id 
     WHERE u1_.user_id = u0_.id AND u2_.id = :group 
    ) 

它看起來像是在做正確的事情太多。

這是一個發現是偶然的答案之一,只是張貼到StackOverflow上沒有搜索谷歌和StackOverflow上幾天:)

有趣的事實結果一無所獲後:你可以用」在Symfony2的./app/console中使用doctrine:query:dql運行這個DQL - 至少當我嘗試替換ID時,它給了我一個錯誤: