我的数据库中有一个表结构,如下所示:
/*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
答案 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()