此SQL查询是否保证正确连接?

时间:2013-02-09 00:22:03

标签: sql inner-join

这是一个非常基本的问题,但出于某种原因,我无法安抚自己。我有一个SQL查询,我想确保按照我的预期行事。

question_recordsenrollmentsquestions

的外键
SELECT `question_records`.* FROM `question_records` 
  INNER JOIN `enrollments` ON `enrollments`.`id` = `question_records`.`enrollment_id` 
  INNER JOIN `questions` ON `questions`.`id` = `question_records`.`question_id` 
  WHERE (enrollments.id IN (10,20) 
         AND questions.id IN (500,600) 
         AND question_records.id not in (3000,4000))

我想要确定的是,我不会得到一个问题记录,例如,enrollment_id为11,question_id为500.换句话说,这个内部联接是否在记录上对此where子句进行处理记录基础?更重要的是,总是对待它吗? (我可以拿出一个测试示例,但是想确保我没有错过一个案例。

编辑:为清晰起见,附加说明:

数据库中可能有一个question_record,其中enrollment_id为11,question_id为500.如果此查询不是按记录搜索条件记录基础,它将匹配question_id 500并返回记录。这不是我想要的行为。我只想要针对给定记录匹配两者 enrollment_id question_id的记录。我得到的答案涵盖了这个条件。

2 个答案:

答案 0 :(得分:0)

用于评估此查询的心理模型是:

  1. 您可以抓取question_recordsenrollmentsquestions中的所有行。
  2. 您可以创建这三个行集的笛卡尔积。 (首先将所有内容与所有内容相匹配。)
  3. INNER JOIN根据ON条件是否为真来过滤笛卡尔积的行。
  4. 然后根据最终WHERE条件对此进行过滤。
  5. 选择所需的列以形成最终结果。
  6. (显然,数据库会将其完全优化为其他内容。)

    因此,如果某一行与INNER JOIN..ON条件匹配,但与WHERE条件不匹配,则它不会出现在最终结果中。它必须符合所有条件。

    当您知道INNER JOIN与此相同时,这可能更容易理解:

    SELECT qr.* FROM question_records qr
                     enrollments      e
                     questions        q
      WHERE e.id = qr.enrollment_id
        AND q.id = qr.question_id
        -- your original WHERE condition
        AND enrollments.id IN (10,20) 
        AND questions.id IN (500,600) 
        AND question_records.id not in (3000,4000))
    

    (此表格与我概述的心理模型相匹配。)

答案 1 :(得分:0)

如果您的问题确实是SQL优化器是否会将WHERE子句中的条件推送到JOIN中,并在执行连接之前将过滤作为每个表的中间结果,那么答案是没有这样的保证但在像这样的简单情况下任何一半体面的优化器都会。

相关问题