mysql更新表使用来自另一个表的数据

时间:2017-02-26 05:05:29

标签: mysql

我的数据库中有一个表结构,如下所示:

/*city*/
+----------+------------+
|    id    |   name     |
|-----------------------|
|    1     | Gotham     |
|    2     | Metropolis |
|    3     | Smallville |
|    4     | Fawcett    |
+----------+------------+   

/*district*/ 
+----------+------------+------------+
|    id    |   name     |   city_id  |
|------------------------------------|
|    1     |     A      |      1     |
|    2     |     B      |      1     |
|    3     |     C      |      2     |
|    4     |     D      |      2     |
|    5     |     E      |      2     |
|    6     |     F      |      3     |
|    7     |     G      |      3     |
|    8     |     H      |      4     |
+----------+------------+------------+

/*distance*/
+----------+-------------+------------------+-------------------------+---------+
|    id    | origin_city | city_destination |  district_destination   |  length |
|---------------------------------------------------------------------|---------|
|    1     |     2       |         2        |            1            |    4    |
|    2     |     3       |         3        |            1            |    5    |
|    3     |     1       |         1        |            2            |    6    |
|    4     |     2       |         2        |            3            |    5    |
|    5     |     4       |         4        |            1            |    8    |
|    6     |     4       |         2        |            4            |    9    |
|    7     |     4       |         3        |            5            |    11   |
|    8     |     1       |         4        |            6            |    13   |
+----------+-------------+------------------+-------------------------+---------+

表区通过 city_id 外键连接到城市表,并且距离表连接到城市和地区表,问题是如果在距离表中,有错误 city_destination district_destination 不匹配的数据,我需要修复此问题,但我不知道如何使用更新查询来解决这类问题,以显示错误city_destination数据我使用此查询:

SELECT a.* FROM distance a, district b WHERE a.district_destination = b.id AND a.city_destination != b.city_id

1 个答案:

答案 0 :(得分:1)

首先,抛弃连接操作的旧式逗号语法。使用JOIN关键字并将连接谓词移动到ON子句。编写一个SELECT查询,返回要更新的现有行(以及PK和要分配的新值。(看起来就像你一样。)

假设我们要替换city_destination表的distance列中的值,并看到此列在功能上依赖于district_destination ...

从一个返回要更新的行的查询开始。

SELECT ce.id                  AS id
     , ce.district_destination AS district_destination 
     , ce.city_destination    AS old_city_destination
     , ct.city_id             AS new_city_destination        
  FROM distance ce
  JOIN district ct
    ON ct.id = ce.district_destination
   AND NOT ( ct.city_id <=> ce.city_destination )
 ORDER BY ce.id

在MySQL中,多表更新非常简单。 MySQL参考手册中记录了该语法。

首先,我们将其作为SELECT编写,使用以前的查询作为内联视图

SELECT t.id
     , s.new_city_destination
  FROM ( SELECT ce.id                  AS id
              , ce.district_destination AS district_destination 
              , ce.city_destination    AS old_city_destination
              , ct.city_id             AS new_city_destination        
           FROM distance ce
           JOIN district ct
             ON ct.id = ce.district_destination
            AND NOT ( ct.city_id <=> ce.city_destination )
          ORDER BY ce.id
       ) s
  JOIN distance t
    ON t.id = s.id

然后我们可以将它转换为UPDATE语句。将SELECT ... FROM替换为UPDATE,并在末尾添加SET子句。 (如果有WHERE子句,则在UPDATE ( SELECT ce.id AS id , ce.district_destination AS district_destination , ce.city_destination AS old_city_destination , ct.city_id AS new_city_destination FROM distance ce JOIN district ct ON ct.id = ce.district_destination AND NOT ( ct.city_id <=> ce.city_destination ) ORDER BY ce.id ) s JOIN distance t ON t.id = s.id SET t.city_destination = s.new_city_destination 子句之前。)

datetime.now()