这是一个非常基本的问题,但出于某种原因,我无法安抚自己。我有一个SQL查询,我想确保按照我的预期行事。
question_records
有enrollments
和questions
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
的记录。我得到的答案涵盖了这个条件。
答案 0 :(得分:0)
用于评估此查询的心理模型是:
question_records
,enrollments
和questions
中的所有行。 INNER JOIN
根据ON
条件是否为真来过滤笛卡尔积的行。 WHERE
条件对此进行过滤。(显然,数据库会将其完全优化为其他内容。)
因此,如果某一行与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中,并在执行连接之前将过滤作为每个表的中间结果,那么答案是没有这样的保证但在像这样的简单情况下任何一半体面的优化器都会。