卡在 DQL 左连接查询上
Stuck on a DQL left join query
我有两个 table:
用户 <----> 问题
他们使用多对多关系 table 来跟踪哪个用户回答了哪个问题。
用户 <----> 用户问题 <----> 问题
现在我需要编写一个查询来获取特定用户 ID 尚未回答的所有问题。
以下本机查询工作正常:
SELECT * FROM questions q
WHERE q.id NOT IN (
SELECT question_id FROM users_questions
WHERE user_id = 4
);
但是我在这个查询中直接访问了 UsersQuestions table,我还没有找到在 Doctrine 中这样做的方法,我什至认为这是不可能的。
访问 table 的唯一方法是加入我的问题 class 的 属性,因此我尝试将查询重写为以下查询,它也可以正常工作作为本机查询:
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 和一般查询的非常基本的了解,这对我来说看起来不错。但是,这会提取 returns table 中的所有问题,而不仅仅是该用户尚未回答的问题。
我是不是哪里弄错了?或者是否有任何 other/easier 方法来获取这些未回答的问题?我觉得我在这里重新发明了轮子。
几天来一直坚持这个问题,我在本机 SQL 中所做的每一次尝试都很好,但我无法将其转换为 DQL。任何帮助将不胜感激。
我已经通过以下查询解决了我的问题。看起来毕竟可以创建子查询。
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 如何处理左连接/空情况有关。但是,我从不同角度处理问题的这个查询非常有效。
我有两个 table:
用户 <----> 问题
他们使用多对多关系 table 来跟踪哪个用户回答了哪个问题。
用户 <----> 用户问题 <----> 问题
现在我需要编写一个查询来获取特定用户 ID 尚未回答的所有问题。
以下本机查询工作正常:
SELECT * FROM questions q
WHERE q.id NOT IN (
SELECT question_id FROM users_questions
WHERE user_id = 4
);
但是我在这个查询中直接访问了 UsersQuestions table,我还没有找到在 Doctrine 中这样做的方法,我什至认为这是不可能的。
访问 table 的唯一方法是加入我的问题 class 的 属性,因此我尝试将查询重写为以下查询,它也可以正常工作作为本机查询:
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 和一般查询的非常基本的了解,这对我来说看起来不错。但是,这会提取 returns table 中的所有问题,而不仅仅是该用户尚未回答的问题。
我是不是哪里弄错了?或者是否有任何 other/easier 方法来获取这些未回答的问题?我觉得我在这里重新发明了轮子。
几天来一直坚持这个问题,我在本机 SQL 中所做的每一次尝试都很好,但我无法将其转换为 DQL。任何帮助将不胜感激。
我已经通过以下查询解决了我的问题。看起来毕竟可以创建子查询。
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 如何处理左连接/空情况有关。但是,我从不同角度处理问题的这个查询非常有效。