在一个UPDATE查询中更新三个表

时间:2014-08-20 15:15:34

标签: mysql

我有三张这样的表:

1 / 主题表:

topic_id    category_id    subject    
   1             1         first
   2             3         second
   3             2         third

2 / 类别表:

category_id    cat_name
     1         art
     2         math

主题表通过外键category_id链接到类别表。

3 / 文章表:

article_id    topic_id    body      date
    1            1        blabla   7/20/2014
    2            1        a reply  7/22/2014

文章表由外键topic_id链接到主题表。此表存储主题的描述(article_id # 1)及其可能的repli(es {(1}})

我有一个表单,主题所有者可以更新表1中的article_id #2,表2中的subject和表格中的category name 3。

假设我可以验证三个必需元素,例如 subject cat_name body ,我从表单提交中获取它们并分配给这三个变量:

body

现在,我想更新$subject = $_POST['subject']; $cat_name = $_POST['cat_name']; $body = $_POST['body']; topic_id #1),其主题,类别名称和正文存储在三个不同的表格中。

您能帮我写一个可以执行此要求的$tid = $_GET['tid'];查询吗?

非常感谢!

P / S:我只能为一个表编写UPDATE查询。现在,我陷入了UPDATE查询。

[已编辑] :为了帮助澄清问题,我想补充一条如下信息:

由于multible-table update是由主题所有者进行的(非所有者无法执行此操作),例如,此处的UPDATE可能/可能不属于特定的所有者/用户article_id#2。因此,请考虑topic_id流程只关注首先与要更新的topic_id一起使用的article_id。

1 个答案:

答案 0 :(得分:1)

MySQL的multi-table UPDATE syntax遵循一般格式:

UPDATE
  t1
  JOIN t2 ON t1.id = t2.t1_id
SET
  t1.col1 = 'new value',
  t2.col2 = 'new value'
WHERE
  <some condition>

您需要通过topic_id加入以收集所有列以进行更新。主要在这里,复杂性在于数据模型在同一个表中列出文章和回复,只有每个article.topic_id组的位置来识别它们。这意味着您需要加入子查询,该子查询返回每个MIN()组的第一个(article_idtopic_id,以确定哪个文章的body应该更新。

UPDATE
  topics t
  INNER JOIN categories c ON t.category_id = c.category_id
  INNER JOIN article a ON t.topic_id = a.topic_id
  /** 
   Subquery retrieves the lowest article_id per topic_id
   The INNER JOIN here will cause only one record from `article` to match
   and be modified.
   */
  INNER JOIN (
    SELECT topic_id, MIN(article_id) AS article_id
    FROM article
    GROUP BY topic_id
    /* Join the subquery against `article` by `article_id` */
  ) first_per_topic ON a.article_id = first_per_topic.article_id
SET
  /* Supply the new values */
  t.subject = ?,
  c.cat_name = ?,
  a.body = ?
WHERE 
  /* Identify the topic_id in the WHERE clause */
  t.topic_id = ?

上面,我使用?占位符假设MySQLi或PDO预处理语句(推荐)。必要时替换新值。

关于这些日期格式的说明7/22/2014 ...除非这只是您在问题中输入的示例数据,否则表明您可能没有在该列上使用a proper DATE data type。建议使用DATE类型以允许MySQL使用其内置的日期处理功能。