gpt4 book ai didi

mysql - Rails/SQL - 从连接查询中排除对象

转载 作者:行者123 更新时间:2023-11-29 08:29:04 25 4
gpt4 key购买 nike

我正在编写一个 Rails 应用程序,用户可以在其中使用问题数据库进行 self 测试。我有用户和问题的表格。当回答问题时,将创建 QuestionAttempt 对象,链接到用户和问题,该对象具有 bool 属性“正确”,存储用户是否正确回答了问题。

我希望允许用户使用以下选项搜索问题:

  1. 显示我之前未尝试过的问题(即此问题/用户不存在 QuestionAttempt 对象)
  2. 显示我之前没有正确回答的问题(即此问题/用户不存在具有正确 == true 的 QuestionAttempt 对象)

鉴于数据库很大,我需要相当有效的查询来执行此操作。我使用以下代码成功实现了第一个查询:

Question.joins("LEFT OUTER JOIN question_attempts ON question_attempts.question_id = questions.id").where("question_attempts.id IS NULL AND question_attempts.user_id = #{user_id}")

这将返回给定用户没有 QuestionAttempt 模型的所有问题。但是,我无法找出第二个问题的必要查询,找到没有 QuestionAttempt 模型且正确 == true 的所有问题。我尝试过以下方法:

Question.joins("LEFT OUTER JOIN question_attempts ON question_attempts.question_id = questions.id").where("question_attempts.user_id = #{user_id} AND (question_attempts.correct = 0 OR question_attempts.id IS NULL)")

这会选择尚未尝试或未正确回答的问题。然而,问题可能已经被尝试了多次,有一些正确的答案,也有一些不正确的答案 - 只要他们至少有一次正确的尝试,我就不想返回这些问题。如何从该查询中排除这些问题?

非常感谢

最佳答案

我相信,为了获得良好的数据库查询,您应该尝试强制 Rails 进入不同的形状,因为最合适的 SQL 语法是:

select ...
from questions
where not exists (
select null
from question_attempts
where question_attempts.question_id = questions.id and
question_attempts.user_id = #{user_id} and
question_attempts.correct = 0)

或者换句话说,“列出该用户没有正确答案记录的问题。”。

因此我只需写:

Question.where("not exists (
select null
from question_attempts
where question_attempts.question_id = questions.id and
question_attempts.user_id = #{user_id} and
question_attempts.correct = 0)")

这可以写成连接,但是一个像样的 RDBMS 查询优化器无论如何都会将不存在转换为反连接,而且我认为这种语法更自然。

关于mysql - Rails/SQL - 从连接查询中排除对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17154331/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com