2

特に「条件はWHERE句ではなくON句に入らなければならない」に関する多くの質問と回答を読んだ後は、これをどうにかして知っておくべきだと思います。しかし、私はまだ迷っています。

私は3つのテーブルを持っており、通常はLEFT(OUTER)結合でそれらを結合します。結合されたテーブルは次のようになります(かなり標準):

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を正しく取得することさえできません)。

そして今、私はquestion_id 2と8を持つタスクだけを取得したいのです(例えば)タスクがそれらのquestion.idの両方を持っていない場合、私はそれを結果セットに入れたくありません。この場合、タスクには他のquestion_idsも含まれる可能性があります。クエリが正確にそれらの2(または他のセット)を持つものだけを返す必要がある場合、クエリがどのように見えるかを確認するのは興味深いことですが。WHERE question.id = 2の場合、1つの質問を持つすべてのタスクを取得するのは簡単ですが、WHERE句のANDは空の結果になります。

4

5 に答える 5

2

WHERE句は、一度に1つの行にのみ条件を適用できます。ただし、異なるIDの質問は、異なる行で発生します。これを解決する方法は?自己結合を使用して、両方の行を1つの行に結合します。

次に例を示します。

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

もう1つの解決策は、質問2または8を持つタスクを見つけてから、GROUP BYおよびHAVINGを使用して、それらのうち2つだけを持つグループでフィルター処理することです。

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
于 2011-08-23T22:46:58.997 に答える
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)
于 2011-08-23T20:44:17.883 に答える
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である必要があります。悪い取引。

于 2011-08-23T20:46:16.380 に答える
0

and ... where question.id IN (2,8) を使用しなくてもこれを行うことができます

于 2011-08-23T20:42:56.727 に答える
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)
于 2011-08-23T20:43:29.263 に答える