2016-05-11 9 views
1

私はこのようなテーブルがあります:私は質問の受け入れ答えを設定する前にこの条件を実装しようとしているUPDATE文でJOINを使用するにはどうすればよいですか?

// QandA 
+----+----------------------------------------+---------+----------+-----------+ 
| Id |     body     | related | accepted | author_id | 
+----+----------------------------------------+---------+----------+-----------+ 
| 1 | content of question1     | null | null  | 12345  | 
| 2 | content of first answer for question1 | 1  | 0  | 53456  | 
| 3 | content of question2     | null | null  | 43634  | 
| 4 | content of second answer for question1 | 1  | 0  | 43665  | 
| 5 | content of first answer for question2 | 3  | 1  | 43324  | 
+----+----------------------------------------+---------+----------+-----------+ 

/* related column: Actually that's just for answers and this column is containing the id of 
    its question. (questions always are null) */ 

/* accepted column: Actually that's just for answers and specifics accepted answer. 
    0 means it isn't accepted answer, 1 means it is accepted answer. 
    (questions always are null) */ 

を:

条件:は、現在のユーザーかどうかを検証OPかどうか。 author_id ofその質問は$_SESSION['id']と同じである必要があります。ここで


は私のクエリです:(私が持っているすべてのデータが受け入れ答え:answer_idだけのIDです)

UPDATE QandA q CROSS JOIN (SELECT related FROM QandA WHERE id = :answer_id) x 
    SET accepted = (id = :answer_id) -- this acts like a if statement 
    WHERE q.related = x.related 
     AND 
     -- validating OP 
     (SELECT 1 FROM QandA 
      WHERE id = x.related AND 
       author_id = $_SESSION['id'] 
     ) 

#1093 - あなたは "ターゲット表を指定することはできませんFROM句での更新のためのtbname '

どうすれば修正できますか?


EDIT:は実際には1つの以上の条件があります:

+----+----------------------------------------+---------+----------+-----------+------+ 
| Id |     body     | related | accepted | author_id | free | 
+----+----------------------------------------+---------+----------+-----------+------+ 
| 1 | content of question1     | null | null  | 12345  | null | 
| 2 | content of first answer for question1 | 1  | 0  | 53456  | null | 
| 3 | content of question2     | null | null  | 43634  | 300 | 
| 4 | content of second answer for question1 | 1  | 0  | 43665  | null | 
| 5 | content of first answer for question2 | 3  | 1  | 43324  | null | 
+----+----------------------------------------+---------+----------+-----------+------+ 

/* free column: Actually that's just for questions. `null` means it is a free question 
    and any number else means it isn't. (answers always are `null`) */ 

追加条件:質問がフリーであれば、OPはそれのための答えを受け入れて、そして彼の受け入れ答えを変更することができます彼の受け入れられた答えを元に戻す。しかし、質問が無料でない場合、OPは一度質問を受け付けることができ、取り消すことはできず、受け入れられた回答を変更することはできません。ここではMySQLの中で、その条件を実施している:

(SELECT 1 FROM QandA 
    WHERE id = x.related AND 
     (
      (free IS NOT NULL AND 
      NOT IN (SELECT 1 FROM QandA 
         WHERE related = x.related AND 
          accepted = 1) 
     ) OR free IS NULL 
     ) 
) 
+0

なぜあなたは、データベースにこのビジネスロジックのすべてを実装しようとしていますか?トランザクションを使用してアプリケーション内で実装する方がよい。 – eggyal

+0

@eggyalこれらの2つの検証はデータベースに依存しています。私は* 1を確認する必要があります。答えを受け入れる現在のユーザーはOP *ですか? * 2。質問が無料でない場合、OPは一度だけ回答を受け入れることができます(受け入れられた回答を取り消したり変更したりすることはできません)* – Shafizadeh

+0

だから?アプリケーションにチェックインするデータを選択し、必要なロジックを実行します。 – eggyal

答えて

1

私は、これはそれを行うべきだと思う:

UPDATE QandA AS ans1 
JOIN QandA AS ans2 ON ans2.related = ans1.related 
JOIN QandA AS ques ON ans2.related = ques.id 
SET ans1.accepted = (ans1.id = :answer_id) 
WHERE ques.author_id = :session_id 
AND ans2.id = :answer_id 

最初JOINフィルタダウン受け入れられて答えとして同じ質問に対する回答に。

第2のJOINがその質問を見つけます。

WHERE句は、指定した著者の質問にのみ更新を制限し、受け入れられる回答IDを指定します。

DEMO

追加条件については、WHERE句に

AND (ques.free IS NULL or ans1.accepted IS NULL) 

を追加します。 ques.free IS NULLは無料の質問と一致し、ans1.accepted IS NULLは回答が受け入れられない質問と一致します(回答が受け入れられた場合、その質問に対するその他の回答はすべてaccepted = 0になるため)。

DEMO of question with no accepted answer
DEMO of question that's free

+0

あなたの答えはすばらしく、私はあなたのクエリを変更しようとしており、現実のニーズに基づいて独自のクエリを作成しようとしていますが、できません。私は自分の質問を編集し、クエリにも実装する必要がある新しい条件を追加しました。あなたがそれをすることができれば、私はあなたに大変感謝します。そうでなければ問題はありません。 – Shafizadeh

+0

'free = 300'とはどういう意味ですか?コメントには、「NULL」または「1」のいずれかを指定できます。 – Barmar

+0

私は '300'を説明するコメントを編集しました。あなたの新しいアップデートが正しく、不完全であることを確認してください。 'WHERE'節に' AND ques.free IS NULL'を追加すると、自由ではない**質問に対してOPは答え**を受け入れることができません。期待される条件は次のとおりです。OPは、**自由に1回** **(1回)*それ以上(OPは元に戻すことも変更もできません)*の回答を受け入れることができます。だから私は条件に 'OR'演算子を加えなければならないと思う。 – Shafizadeh

関連する問題