坚持DQL左连接查询

时间:2015-06-03 16:40:25

标签: mysql doctrine-query

我有两张桌子:

用户< ---->问题

他们使用ManyToMany关系表来跟踪哪个用户回答了哪个问题。

用户< ----> UsersQuestions< ---->问题

现在我需要编写一个查询来获取特定用户ID尚未回答的所有问题。

以下原生查询可以正常工作:

SELECT * FROM questions q
WHERE q.id NOT IN (
    SELECT question_id FROM users_questions 
    WHERE user_id = 4
);

但是我直接访问了此查询中的UsersQuestions表,但我还没有找到在Doctrine中这样做的方法,我甚至认为它不可能。

访问该表的唯一方法是加入我的Question类的属性,因此我尝试将查询重写为以下的查询,该查询也适用于本机查询:

SELECT * questions q
LEFT JOIN users_questions uq
    ON q.id = uq.question_id AND uq.user_id = 4
WHERE uq.user_id IS NULL;

我假设我可以简单地将其重写为DQL,如下面的查询:

SELECT q FROM MyBundle:Question q
LEFT JOIN q.usersAnswered uq WITH uq.id = 4 
WHERE uq.id IS NULL

当我调用$ query-> getSql()时,我得到以下输出:

SELECT * FROM mybundle_questions g0_ 
LEFT JOIN users_questions u2_ 
    ON g0_.id = u2_.question_id 
LEFT JOIN mybundle_users g1_ 
    ON g1_.id = u2_.user_id AND (g1_.id = 4) 
WHERE g1_.id IS NULL

鉴于我对Doctrine和一般查询的基本知识,对我来说看起来很好。但是,这会获取并返回表格中的所有问题,而不仅仅是此用户尚未回答的问题。

我在某处犯了错误吗?或者有没有其他/更简单的方法来获取这些未回答的问题?我觉得我在这里重新发明轮子。

已经坚持了几天,我在本机SQL中进行的每一次尝试都运行良好,但我无法将其翻译为DQL。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我已通过以下查询解决了我的问题。看起来毕竟可以创建一个子查询。

SELECT q FROM MyBundle:Question q
WHERE q.id NOT IN (
    SELECT uq.id FROM MyBundle:User u 
    INNER JOIN u.questionsAnswered uq 
    WHERE u.id = 4
)

哪个Doctrine转换为以下查询:

SELECT * FROM myBundle_questions g0_
WHERE g0_.id NOT IN (
    SELECT g1_.id FROM myBundle_users g2_ 
    INNER JOIN users_questions u3_ 
        ON g2_.id = u3_.user_id 
    INNER JOIN myBundle_questions g1_ 
        ON g1_.id = u3_.question_id 
    WHERE g2_.id = ?
)

出于某种原因,之前的查询虽然在我看来看起来不错,却没有用。必须与Doctrine如何处理左连接/ null情况有关。但是,我从不同角度处理问题的查询工作完美。