mysql - 如何在 UPDATE 语句中使用 JOIN?

标签 mysql sql join sql-update

我有一个这样的表:

// 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']相同。


这是我的查询:(我拥有的所有数据只是已接受答案的 ID :answer_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 - You can't specify target table 'tbname' for update in FROM clause

我该如何解决?


编辑:其实还有一个条件:

+----+----------------------------------------+---------+----------+-----------+------+
| 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
        )
)

最佳答案

我认为应该这样做:

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 筛选出与被接受的答案相同的问题的答案。

第二个 JOIN 找到那个问题。

WHERE 子句将更新仅限于给定作者的问题,并指定接受的答案 ID。

DEMO

对于附加条件,添加

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

WHERE 子句。 ques.free IS NULL 匹配任何自由问题,ans1.accepted IS NULL 匹配没有接受答案的问题(因为当一个答案被接受时,所有其他答案该问题得到 accepted = 0)。

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

关于mysql - 如何在 UPDATE 语句中使用 JOIN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37160002/

相关文章:

php - SQL JOIN有条件地包含多行

mysql - 增加表中所有列的 varchar() 大小?

sql - PostgreSQL 选择每日最大值和相应的发生时间

sql - 将单列值标签连接到 SQL 中另一个表中的多列值

mysql - 在使用别名的 having 子句中使用子查询

sql - 如何从表中加入 COUNT,然后用另一个 JOIN 影响该 COUNT

sql-server - 具有多个表和键的 INNER JOIN

mysql - SELECT a number 是什么意思?

php - 来自另一台服务器的安全 MySQL 连接

mysql - 标准化 m :s to h:m:s