我想我应该知道这一点,特别是在阅读了很多关于“条件必须进入ON子句而不是WHERE子句”的问题和答案之后。但是,我还是输了。
我有三个表,我通常使用LEFT(OUTER)连接加入它们。连接表看起来像这样(retty标准):
task_id task_questions_taskId taskQuestions_questionId question_id 1 1 5 5 1 1 8 8 2 2 8 8
SELECT `t`.`id` AS `task_id` ,
`task_questions`.`taskId` AS `task_questions_taskId` ,
`task_questions`.`questionId` AS `task_questions_questionId` ,
questions.id AS question_id
FROM `task` `t`
LEFT OUTER JOIN `task_questions` `task_questions`
ON ( `task_questions`.`taskId` = `t`.`id` )
LEFT OUTER JOIN `question` `questions`
ON ( `task_questions`.`questionId` = `questions`.`id` )
这是获取所有记录的标准查询。 (它来自Yii;我实际上想要使用Active Record,但是甚至无法获得普通的SQL)。
现在我想得到那些有问题2和8(例如)的任务 因此,如果任务没有这两个question.ids,我不希望它在结果集中。 在这种情况下,任务也可以有其他question_ids。虽然如果它只返回那些具有那些2(或任何其他集合)的那些查询将会如何看起来会很有趣。 使用WHERE question.id = 2,很容易得到所有有一个问题的任务, 但是WHERE子句中的AND会导致空结果。
答案 0 :(得分:1)
WHERE子句一次只能将条件应用于一行。但是你对不同id的问题出现在不同的行上。怎么解决这个?使用自联接将两行连接到一行。
以下是一个例子:
SELECT t.`id` AS `task_id`, ...
FROM `task` AS t
INNER JOIN `task_questions` AS tq2 ON ( tq2.`taskId` = t.`id` )
INNER JOIN `questions` AS q2 ON ( tq2.`questionId` = q2.`id` )
INNER JOIN `task_questions` AS tq8 ON ( tq8.`taskId` = t.`id` )
INNER JOIN `questions` AS q8 ON ( tq8.`questionId` = q8.`id` )
WHERE q2.`id` = 2 AND q8.`id` = 8
另一个解决方案是找到有问题2 OR 8的任务,然后使用GROUP BY和HAVING按照其中两个具有正确值的组进行过滤。
SELECT t.`id` AS `task_id`, ...
FROM `task` AS t
INNER JOIN `task_questions` AS tq ON ( tq.`taskId` = t.`id` )
INNER JOIN `questions` AS q ON ( tq.`questionId` = q.`id` )
WHERE tq.`questionId` IN (2, 8)
GROUP BY t.`id`
HAVING COUNT(DISTINCT q.`id`) = 2
答案 1 :(得分:0)
即使没有使用和,你也可以这样做 ...其中question.id IN(2,8)
答案 2 :(得分:0)
使用IN
:
SELECT `t`.`id` AS `task_id` ,
`task_questions`.`taskId` AS `task_questions_taskId` ,
`task_questions`.`questionId` AS `task_questions_questionId` ,
questions.id AS question_id
FROM `task` `t`
LEFT OUTER JOIN `task_questions` `task_questions`
ON ( `task_questions`.`taskId` = `t`.`id`)
LEFT OUTER JOIN `question` `questions`
ON ( `task_questions`.`questionId` = `questions`.`id` )
WHERE `task_questions`.`questionId` IN (2, 8)
答案 3 :(得分:0)
这应该这样做
SELECT `t`.`id` AS `task_id` ,
`task_questions`.`taskId` AS `task_questions_taskId` ,
`task_questions`.`questionId` AS `task_questions_questionId` ,
questions.id AS question_id
FROM `task` `t`
LEFT OUTER JOIN `task_questions` `task_questions`
ON ( `task_questions`.`taskId` = `t`.`id` )
LEFT OUTER JOIN `question` `questions`
ON ( `task_questions`.`questionId` = `questions`.`id` )
WHERE questions.id in (2,8)
答案 4 :(得分:0)
你不是在寻找AND,而是在寻找OR,或者是IN:
WHERE `questions`.`id` IN (2,8) -- grab everything in the parens.
或
WHERE `questions`.`id` = 2 OR -- grab each item individually
`questions`.`id` = 8
如果您使用AND
,那意味着ID必须同时为8和2。糟糕的交易。